jemmons
(Joshua Scott Emmons)
1
Given a standard-looking (I think?) curry function:
func curry<T, U, Z>(_ ƒ: @escaping (T, U) -> Z) -> (T) -> (U) -> Z {
return { t in
return { u in
ƒ(t, u)
}
}
}
and a higher-order-looking function like:
func higherOrder(_ x: String, _ y: @escaping (String) -> Int) { }
currying off the first param makes the type of the resulting function unknowable:
type(of: curry(higherOrder)("foo"))
//> ((String) -> Int) -> ()
curry(higherOrder)("foo") is ((String) -> Int) -> ()
//> false?!?!
First, am I doing this right, or is my syntax for expressing types off?
If it looks correct, is this a known thing? Are there workarounds?
1 Like
jemmons
(Joshua Scott Emmons)
2
This might be a more general issue related to stuffing a whole function into a single generic placeholder and then stuffing that into the param of another function:
func putInParam<T>(_ x: T) -> (T)->Void {
return { (_: T)->Void in }
}
type(of: putInParam({ (_: String)->Void in }))
//> ((String) -> ()) -> ()
putInParam({ (_: String)->Void in }) is ((String) -> ()) -> ()
//> false
Giving it a non-function works fine:
putInParam("foo") is (String) -> ()
//> true
Or putting it into the return instead of the params also works:
func putInReturn<T>(_ x: T) -> ()->T {
return { return x }
}
putInReturn({ (_: String)->Void in }) is () -> (String) -> ()
//> true
It feels like I'm missing some subtlety of the type syntax. Like by wrapping a function in parens to indicate it's the parameter of another function, I'm accidentally asking swift to treat it like a tuple or something.
afarnham
(Aaron Farnham)
3
The type(of:) function is not actually showing the whole type when you print it. you need to include the @escaping in your is clause.
e.g.:
curry(higherOrder)("foo") is (@escaping (String) -> Int) -> ()
1 Like
tomassliz
(Tomas Sliz)
4
@jemmons You can check "A problem" section in the episode about Higher-Order Functions on pointfree.co . I hope it helps!
In short: you have to use a little helper function (with a cool name zurry) that lowers a function that takes no arguments to just the value that it returns.