Search code examples
swiftfunction-composition

Generic curried map function


I try to write map function as curried and flipped. (First transform function then collection). I did write function and compiler accepted it. But I am unable to call it. Compiler gives there is no map func with supplied arguments. Anyway here is the function that I wrote:

func map <A: CollectionType, B> (f: (A.Generator.Element) -> B) -> A -> [B] {
    return { map($0, f) }
}

And this is the test code:

func square(a: Int) -> Int {
    return a * a
}

map(square)

Note: Code is written inside playground with Xcode 6.3 beta 2


Solution

  • The problem here is that map is not locked-down enough – what kind of collection is A? You can’t write a generic function that generates a generic function – when you call it, the types of all the placeholders have to be fully determined.

    This means you can call your map function, as defined, so long as you fully specify the types of A and B:

    // fixes A to be an Array of Ints, and B to be an Int
    let squarer: [Int]->[Int] = map(square)
    
    squarer([1,2,3])  // returns [1,4,9]
    
    // fixes A to be a Slice of UInts, and B to be a Double
    let halver: Slice<UInt>->[Double] = map { Double($0)/2.0 }
    
    halver([1,2,3])   // returns [0.5, 1, 1.5]