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.