2017-09-09 5 views
1

Ich versuche, die folgende Scala Code kompilieren, um herauszufinden, warum?Scala Funktion akzeptiert verschiedene Arten

trait List[+A] 
case object Nil extends List[Nothing] 
case class Cons[+A](head: A, tail: List[A]) extends List[A] 

def map[A, B](as: List[A])(f: A => B): List[B] = as match { 
    case Nil   => Nil 
    case Cons(x, xs) => Cons(f(x), map(xs)(f)) 
} 

def tester[A, B](as: List[A])(f1: A => List[B]) = map(as)(f1) 

Gemäß meinem Verständnis tester sollte nicht kompiliert werden, weil die Definition von map sagt es zwei Parameter akzeptiert: eine Liste Liste eine Funktion vom Typ A => B.

jedoch in tester Funktion habe ich Funktion f1 die vom Typ ist A => List[B], so, wie die Art des Ungleichgewichts Argumente, dachte ich, dass der Compiler Fehler auslösen sollte. Aber der Code ist in Ordnung.

Könnten Sie mir bitte helfen, zu verstehen, warum der Code hier kompiliert?

+0

'.map' sollte einen Typparameter' A' erklären, andernfalls wird man den Typ-Parameter 'A' am Zug Ebene Schatten (und ist ohnehin in diesem Fall nutzlos) – cchantep

+0

@cchantep' map' ist außerhalb des Merkmals. – HTNW

Antwort

2

Im tester[A,B] Methode sind Sie in der Tat ruft map[A, List[B]].

Vielleicht ist der Code leichter zu verstehen, wenn Sie die Tester-Methode mit einem anderen Typparameter schreiben, dann im Aufruf von map, A = C und B = List[D].

def tester[C, D](as: List[C])(f1: C => List[D]): List[List[D]] = { 
    map[C, List[D]](as)(f1) 
} 
+0

Danke für die Antwort. Ich habe tatsächlich vergessen, dass der Scala-Compiler die Art der Parameter aus dem übergebenen Argument ableitet. Wie auch immer, ich verstehe immer noch nicht, warum in der Testmethode die Karte tatsächlich map [A, List [B]] ist? Was die Art der Liste als [A] und der Typ von f1 ist A => Liste [B]. Sollte also die Karte nicht map sein [Liste [A], A => Liste [B]]? – Somenath

+0

@Somenath Der Compiler leitet die Typparameter von map so ab, dass die Argumente 'as' und' f' im Aufruf kompatibel sind. Da 'f1: A => Liste [B]', muss 'map'' map [A, Liste [B]] 'sein – Harald

1

denke ich, Ihr Missverständnis kommt von der Tatsache, dass Sie gehen davon aus, dass die A und B Typen sowohl auf map und tester gemeinsam sind, während sie tatsächlich lokal definiert sind. Für die Zwecke dieses Beispiels wollen wir die B von tester in C umbenennen. Dies bedeutet, dass die B von map tatsächlich List[C] sein wird.

Verwandte Themen