Search code examples
swiftnested-function

Creating a function with generics that returns another function in Swift


My question is based on the Swift's book's Guided Tour chapter where the following code is given:

func anyCommonElements <T, U where T: Sequence, U: Sequence,
      T.GeneratorType.Element: Equatable,
      T.GeneratorType.Element == U.GeneratorType.Element>
      (lhs: T, rhs: U) -> Bool 
{
    for lhsItem in lhs {
        for rhsItem in rhs {
            if lhsItem == rhsItem {
                return true
            }
        }
    }
    return false
}
anyCommonElements([1, 2, 3], [3])

The book asked to experiment with modifying the function to return an array of common elements instead, which I was able to do.

But I began experimenting with trying to modify the function to return another function that builds up the array and that's what I'm having problems with.

Here is what I have:

func myCommonElements<T, U where T: Sequence, U: Sequence,
    T.GeneratorType.Element: Equatable,
    T.GeneratorType.Element == U.GeneratorType.Element>
    (lhs: T) -> (U -> Array<U.GeneratorType.Element>)
{
    func makeCommon (rhs: U) -> Array<U.GeneratorType.Element>
    {
        var commonArray = Array<U.GeneratorType.Element>()
        for lhsItem in lhs {
            for rhsItem in rhs {
                if lhsItem == rhsItem {
                    commonArray.append(lhsItem)
                }
            }
        }
        return commonArray
    }
    return makeCommon
}

let gatherCommon = myCommonElements([3, 4, 5, 6])
let result = gatherCommon([1, 2, 3, 4])
println(result)

The error that I get is:

cannot convert the expression's type 
'(rhs: $T2 -> Array<$T4>)' to type 'Generator'

I understand the error but I'm not sure why I'm getting this error. What did I do wrong?


Solution

  • When you call myCommonElements you pass the type T as an argument. How can the compiler infer the type for U?? Declare the return type and you will be fine.

    let gc: Array<Int> -> Array<Int> = myCommonElements([3,4,5,6])