2017-01-01 3 views
0

Schreiben dieser Art Prüfung fehlschlägt: Warum funktioniert das Definieren einer Umbruchmethode über eine andere Methode mit einem impliziten Argument nicht?

val list = List(1,3,5,2,4) 

list sortBy (i => -i) //this is ok 

def wrappedSort[A,B](a: List[A])(by: A => B): List[A] = { 
    a sortBy by 
} // this fails type check 

wrappedSort(list)(i => -i) //So this won't work either 

Wir wissen, dass der Compiler-Fehler ist: No implicit Ordering defined for B.

Um es ich zu machen Arbeit hatte die Wrapper-Methode haben die gleiche implizite Argument wie die denen des gewickelt Verfahren ist :

import math.Ordering 

def wrappedSort[A,B](a: List[A])(by: A => B)(implicit ord: Ordering[B]): List[A] = { 
    a sortBy by 
} 

Aber das ist ziemlich ärgerlich. Wenn ich über einen Bibliothekscode abstrahiere oder erweitere, stoße ich auf einige komplizierte Kontextgrenzen, die ich manuell neu implementieren muss. Gibt es dafür einen Workaround, bei dem ich das implizite Argument in meinen eigenen Abstracions nicht angeben muss?

+1

Sie müssen nur 'Ordnen' Kontext an' B', wie folgt hinzufügen: 'def wrappedSort [A, B: Bestellung]' – adamwy

+0

Nicht sicher, was Sie fragen. Gibt es eine Möglichkeit, eine Liste ohne Reihenfolge zu sortieren? Nein ... – Dima

Antwort

3

In diesem Fall ist PreDef (das sich im Umfang befindet, außer Sie es ausdrücklich in dem Compiler deaktivieren) gibt es eine Instanz von Ordering[Int] verfügbar. Daher schlägt der Compiler nicht fehl, weil er im Umfang ist und genau den impliziten Code kennt, nach dem er suchen muss. Wenn Sie eine abstrakte B mit dieser Funktionssignatur angeben, teilen Sie dem Compiler effektiv mit, dass B nicht mit einer Ordering für alle B (die effektiv jeden einzelnen Typ im bekannten Universum ist) und die Anforderung B eine Ordering wie diktiert geliefert werden durch die sortBy Funktion auf List ist sofort fehlgeschlagen.

Es gibt wirklich keine Möglichkeit, dies zu vermeiden, oder sollten Sie es überhaupt vermeiden wollen. Es ist durch das Design und eine Sicherheitsfunktion des Compilers.

+0

Danke, das macht jetzt wirklich Sinn, dass ich tief darüber nachdenke. – shayan

Verwandte Themen