2010-08-11 144 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(_)(_)