2011-11-29 3 views
6

Jaka jest różnica między tymi? Wiem, że ich sygnatury typów są różne i że wszystkie funkcje zaczynają się od normalnego i muszą być .tupled, aby uzyskać ich zduplikowaną formę. Jaka jest zaleta korzystania z niezwikłanych (ale nieskrępowanych) funkcji? Szczególnie dlatego, że wydaje mi się, że przekazywanie wielu argumentów do funkcji dublującej automagicznie ją rozpakowuje, tak przez wszystkie wyglądy są one takie same.Scala: funkcje normalne a funkcje korkowane?

Jedną z różnic jest to, że widzę to zmusza mieć typy dla każdej liczby argumentów funkcji: Function0, Function1, Function2, Function3 etc, natomiast tupled funkcje są tylko Function1[A, R], ale to wydaje się spowolnienia. Jaka jest duża zaleta używania nieekranowanych funkcji, które są domyślne?

Odpowiedz

7

Funkcje zmiennoprzecinkowe wymagają utworzenia obiektu krotki, gdy zostaną wywołane (chyba, że ​​argumenty są już spakowane w krotkę). Nieuliczne funkcje definiują po prostu metodę, która pobiera odpowiednią liczbę argumentów. W związku z tym, biorąc pod uwagę architekturę JVM, funkcje nieokupowane są bardziej wydajne.

3

Rozważmy następujący przykład:

scala> def mult = (x: Int, y: Int) => x * y 
mult: (Int, Int) => Int 

scala> val list = List(1, 2, 3) 
list: List[Int] = List(1, 2, 3) 

scala> list zip list map mult 
<console>:10: error: type mismatch; 
found : (Int, Int) => Int 
required: ((Int, Int)) => ? 
       list zip list map mult 
           ^

scala> list zip list map mult.tupled 
res4: List[Int] = List(1, 4, 9) 

Istnieje wiele sytuacji, gdzie kończą się parowanie elementów krotki. W takich sytuacjach do jej obsługi potrzebna jest funkcja krotki. Ale jest wiele innych miejsc, w których jest to , a nie prawdziwe! Na przykład:

scala> list.foldLeft(1)(mult) 
res5: Int = 6 

scala> list.foldLeft(1)(mult.tupled) 
<console>:10: error: type mismatch; 
found : ((Int, Int)) => Int 
required: (Int, Int) => Int 
       list.foldLeft(1)(mult.tupled) 
            ^

Więc w zasadzie, Scala ma dychotomii między krotki i parametrów, co oznacza, że ​​trzeba konwertować funkcji z tupled do untupled i vice versa tu i tam.