2010-08-11 75 views

回答

21
scala> val f : Int => Int => Int = a => b => a + b 
f: (Int) => (Int) => Int = <function1> 

scala> Function.uncurried(f) 
res0: (Int, Int) => Int = <function2> 
+3

奇怪的是'FunctionN'本身没有'uncurried'方法吗? – 2010-08-11 10:59:13

+1

要在Function1上使用不安全的方法,您需要将其可接受的目标限制为返回函数的函数。也就是说Function1类型的函数[A,Function1 [B,C]]。这可能可以通过广义类型约束来完成,但是这些在Scala 2.8之前是不可用的。 – 2010-08-11 13:32:12

13

扩展retonym的答案,为了完整性还提供了功能对象

val f : Int => Int => Int = a => b => a + b 
val g: (Int, Int) => Int = Function.uncurried(f) 
val h: ((Int, Int)) => Int = Function.tupled(g) 

对于这两项操作相反的功能,让你可以倒着写上面的,如果你想

val h: ((Int, Int)) => Int = x =>(x._1 + x._2) 
val g: (Int, Int) => Int = Function.untupled(h) 
val f : Int => Int => Int = g.curried //Function.curried(g) would also work, but is deprecated. Wierd 
9

为了圆满答案,虽然有一个库方法可以做到这一点,但它也可能是有益的:

scala> val f = (i: Int) => ((s: String) => i*s.length) 
f: (Int) => (String) => Int = <function1> 

scala> val g = (i: Int, s: String) => f(i)(s) 
g: (Int, String) => Int = <function2> 

或一般,

def uncurry[A,B,C](f: A=>B=>C): (A,B)=>C = { 
    (a: A, b: B) => f(a)(b) 
} 
0

类似于雷克斯克尔的答案,但更容易阅读。

type A = String 
type B = Int 
type C = Boolean 

val f: A => B => C = s => i => s.toInt+i > 10 

val f1: (A, B) => C = f(_)(_) 
相关问题