2012-01-05 26 views
5

Curried ve uncurried jenerik fonksiyonları arasındaki tip denetimi farkı karıştı biraz değilim:Genel tip birleştirme: birden çok parametre (T, T) ve çoklu parametre listeleri (T) (T)?

scala> def x[T](a: T, b: T) = (a == b) 
x: [T](a: T, b: T)Boolean 
scala> def y[T](a: T)(b: T) = (a == b) 
y: [T](a: T)(b: T)Boolean 

Benim sezgi hem x(1, "one") ve y(1)("one") tip hataları vermelidir olmasıydı, ama yanılmışım:

scala> x(1, "one") 
res71: Boolean = false 
scala> y(1)("one") 
<console>:9: error: type mismatch; 
found : java.lang.String("one") 
required: Int 
       y(1)("one") 
       ^

ilk başta oluyor örtülü döküm çeşit olduğunu düşündüm, ama bu durumda olması görünmüyordu:

scala> x(1 :Int, "one" :String) 
res73: Boolean = false 

Peki neler oluyor? Sezgim ne olmalı?

+0

Uzun zaman önce bunun bir kopyasını gördüm. Ayrıca bu [neredeyse] kesin durumun SLS'de belgelendiğine inanıyorum. –

+0

İşte başlıyoruz. Başlığı SLS :) –

cevap

9

Sanırım ilk durumda, her iki argümanda da T: Herhangi bir şey var. İkincisi, Int için köreliyor ve sonra String üzerinde başarısız oluyor.

Bu beni ayı gibi görünüyor:

scala> y(1)_ 
res1: Int => Boolean = <function1> 
+0

Ok'da ele alınan önemli terim "çoklu parametre listeleri" ile güncelledim. Bu muhtemelen, 'y (1: Any) ("merhaba") '' false' döndürdüğü için görünüyor. – rampion

+0

Bu –

+0

ile ilgili daha fazla kanıt için düzenlemeye bakın. İlginç bir yan not olarak, bu soru burada yapılan iddiayı çağırıyor gibi görünüyor: http://www.scala-lang.org/node/262 "o zaman f (x) (y) ve g (x, y) aynı kodun içine derlenmiştir. " –

10

Scala bir seferde türleriyle bir parametre bloğu belirlemeye çalışır.

Elbette
def x[T](a: T, b: T)(c: T) = (a == b) 
scala> x(1, "one") _ 
res0: Any => Boolean = <function1> 

, hem Int ve StringAny (ve == tanımlanır Any üzerine) vardır: Uygulamak kısmen başka bir parametre eklemek ve varsa bu görebilirsiniz. önceki bir blokta kullanılmayan

Tipi parametreleri sonraki bir blokta kullanılmak üzere serbest kalır: Daha sonra bloklar halinde varsayılan değerler olarak önce takoz kullanabilirsiniz

def y[T,U](a: T)(b: U)(c: (T,U)) = (a == b) 
scala> y(1)("one") 
res1: (Int, java.lang.String) => Boolean = <function1> 

!

def z[T,U](a: T)(b: U)(c: (T,U) = (a,b)) = (c._1 == c._2) 
scala> z(1)("one")() 
res2: Boolean = false 

Bu nedenle, çok sayıda parametre blokları arasında Parametrelerinizi dağıtılmasına tür kesmesi ve varsaymak için (ve kısmi uygulama için), her iki sonucu vardır.