def curry[A,B,C](f: (A, B) => C): A => (B => C) =
(a: A) => f(a, _)
def curry[A,B,C](f: (A, B) => C): A => (B => C) =
(a: A) => (b: B) => f(a, b)
What I was thinking was that in the first implementation I would take the function f and pass in an A and an anything (but the compiler will type check that the second param is a B) to get a C out.
Yes, they are identical. If you compile:
object Test {
def curry[A,B,C](f: (A, B) => C): A => (B => C) =
(a: A) => f(a, _)
def curry2[A,B,C](f: (A, B) => C): A => (B => C) =
(a: A) => (b: B) => f(a, b)
}
with -Xprint:typer, you get the intermediate abstract syntax tree:
[[syntax trees at end of typer]]
package <empty> {
object Test extends scala.AnyRef {
def <init>(): Test.type = {
Test.super.<init>();
()
};
def curry[A, B, C](f: (A, B) => C): A => (B => C) = ((a: A) => ((x$1: B) => f.apply(a, x$1)));
def curry2[A, B, C](f: (A, B) => C): A => (B => C) = ((a: A) => ((b: B) => f.apply(a, b)))
}
}
During the "typer" stage, when the compiler assigns types to everything, it realizes that the _ (now named x$1) must be type B.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With