2010-08-11 7 views
17

Wenn ich habe:Wie bekomme ich (a, b) => c von a => b => c in Scala?

val f : A => B => C 

Dies ist eine Abkürzung für:

val f : Function1[A, Function1[B, C]] 

Wie ich eine Funktion g mit der Unterschrift erhalten Sie:

val g : (A, B) => C = error("todo") 

(ie)

val g : Function2[A, B, C] //or possibly 
val g : Function1[(A, B), C] 

in Bezug auf f?

Antwort

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

Seltsam, dass es an 'FunctionN' selbst keine' uncurried' Methode gibt? –

+1

Um eine uncurried-Methode für Function1 zu haben, müssten Sie die zulässigen Ziele davon auf Funktionen beschränken, die Funktionen zurückgeben. Das heißt Funktionen mit dem Typ Function1 [A, Function1 [B, C]]. Dies könnte wahrscheinlich mit generalisierten Typ-Constraints geschehen, aber diese waren erst ab Scala 2.8 verfügbar. –

13

Erweiterung retonym Antwort auf Vollständigkeit

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) 

Die Umkehrung Funktionen für diese beiden Operationen auch auf das Funktionsobjekt zur Verfügung gestellt werden, so dass Sie die nach hinten oben schreiben könnte, wenn Sie

wollte
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

Um nur die Antwort abzurunden, obwohl es eine Bibliotheksmethode gibt, um dies zu tun, kann es auch lehrreich sein, es von Hand zu tun:

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> 

oder allgemein

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

ähnlich wie die Antwort von Rex Kerr aber leichter zu lesen.

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(_)(_) 
Verwandte Themen