Created
January 20, 2019 00:54
-
-
Save jemmons/cfe048d35fd6ca4c17a8a66625d4efcc to your computer and use it in GitHub Desktop.
Currying higher-order functions results in broken types.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
// Given what seems to be a pretty standard definition of `curry`… | |
public func curry<T, U, Z>(_ ƒ: @escaping (T, U) -> Z) -> (T) -> (U) -> Z { | |
return { a in | |
return { b in | |
ƒ(a, b) | |
} | |
} | |
} | |
// Currying non-function arguments works fine. | |
func lowerOrder(_ x: String, _ y: String) { } | |
curry(lowerOrder) is (String) -> (String) -> Void | |
//> true | |
// But currying a higher-order function leaves us with some unknowable, unmatchable type! | |
func higherOrder(_ x: String, _ y: (String) -> Int) { } | |
curry(higherOrder) is (String) -> ((String) -> Int) -> Void | |
//> false?!?! | |
// Even though it looks like the type ought to be correct. | |
print(type(of: curry(higherOrder))) | |
//> (String) -> ((String) -> Int) -> () | |
// It only seems to be a problem when function types are in the params. Returning a function works fine. | |
func maker(_ x: String, _ y: String) -> (String)->Int { return { _ in 42 }} | |
curry(maker) is (String) -> (String) -> (String)->Int | |
//> true | |
// And just to be sure it's not a problem with any signature with this shape, this works fine. | |
func staticDef(_ x: String) -> ((String) -> Int) -> Void { return { _ in 42 }} | |
staticDef is (String) -> ((String) -> Int) -> Void | |
//> true |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment