2010-08-11 6 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'? –

+1

Чтобы использовать метод uncurried для Function1, вам необходимо ограничить приемлемые цели его функциями, возвращающими функции. То есть функции с типом Function1 [A, Function1 [B, C]]. Вероятно, это можно было бы сделать с ограничениями обобщенного типа, но они не были доступны до Scala 2.8. –

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(_)(_) 
Смежные вопросы