Search code examples
swiftgenericsfunctional-programming

How can I define `unlines` function generically?


I would like to define a unlines function which works which any Sequence whose elements conform to the StringProtocol; this is my attempt:

func unlines<S: StringProtocol>(_ xs: Sequence<S>) -> S {
    return xs.joined(separator: "\n")
}

Error: Use of protocol 'Sequence' as a type must be written 'any Sequence'

A version defined for a concrete type does work:

func unlines(_ xs: [String]) -> String {
    return xs.joined(separator: "\n")
}

but can only be applied with list of String.

How can I develop a general definition ?

EDIT:

For example, I would like to apply it to the following value:

["Hello", "World"].lazy.map { $0.lowercased() }

Solution

  • joined returns a String so you need to change the return type and use any Sequence

    func unlines<S: StringProtocol>(_ xs: any Sequence<S>) -> String {
        return xs.joined(separator: "\n")
    }
    

    This then works both with String and Substring

    String example:

    let result = unlines(["A", "B", "C"])
    

    Substring example:

    let result = unlines("A-B-C".split(separator: "-"))
    

    both returns

    A
    B
    C