Reputation: 1426
I have a function, which takes two arguments and returns a single value.
For example
func sum(x: Int, y: Int) -> Int {
return x + y
}
Next step is to use a currying
to get a function which takes the only first argument and return a closure with an appropriate signature.
Also, I wrote a type alias to bring more clearness of the result type.
typealias EscapingClosure<A, B> = (A) -> B
func curry<A, B, C>(_ f: @escaping (A, B) -> C) -> EscapingClosure<A, (B) -> C> {
return { (a: A) -> ((_ b: B) -> C) in
return { (b: B) -> C in f(a, b) }
}
}
But then I remembered about uncurry
function which should return a default sum
function signature if I'll apply it on the curryied result.
So I tried to implement a variation of uncurry
, and what I'll get at the result:
func uncarry<A, B, C>(_ f: @escaping EscapingClosure<A, (B) -> C>) -> (A, B) -> C {
return { (a: A, b: B) -> C in
return f(a)(b)
}
}
But here's a problem - I can't use this uncurry
function with the result of currying on sum
function, because uncurry
requires only @escaping parameter where curryied function returns a non-escaping variation.
Here's a Swift compiler error:
Cannot convert value of type '((A) -> Void) -> ()' to expected argument type '(_) -> (_) -> _'
Does anyone know are there any ways to create uncurry
function in Swift which would be applicable to the curryied function result.
Upvotes: 1
Views: 246
Reputation: 63167
Your uncurry
function can do just that, uncurry curried functions:
let currableSum = curry(sum)
let uncurriedSum = uncurry(currableSum)
let add100 = currableSum(100)
print(add100(23)) // => 123
print(uncurriedSum(2, 2)) // => 4
The issue is that you're mistaking uncurrying for unapplying. Once you've partially or fully applied a curried function (or any function, for that matter), there's no mechanism to go back, to get the original function that produced the result.
uncurry(add100) // ❌ can't "unapply" a partially applied function
Imagine if that were the case. Every integer, string, and other value would have to remember a history of what functions caused it. I can't think of a single use case for that. For one, it would require dynamic typing (or forced compile-time casting in a static language like Swift), because you can't predict the signature of an arbitrary function that produces a given result.
Upvotes: 2
Reputation: 1426
As @Alexander write above, I can easily use uncurry
function for curried result of the sum()
.
I just made an error when passed a result value of the curried function.
Upvotes: 0