2016-04-10 15 views
4

ich so etwas wie dies tun wollen:Wie kann ich einen Negationstyp in Scala haben?

def iDontLikeStrings(arg: Not[String]) = {....} 

Im Grunde ist dies kompilieren sollte:

iDontLikeStrings(23) 
iDontLikeStrings(true) 

Und dies nicht kompilieren sollte:

meine Implementierung ist
iDontLikeStrings("hello") 
+0

Nur neugierig, können Sie ein praktisches Beispiel dafür geben, wann Sie das verwenden würden? –

+0

Kaum jemals - der Negationstyp ist ein winziger Schritt über 'Any' :) – pathikrit

+0

Nicht sicher, es ist sogar ein Schritt - Unendlichkeit minus Eins ist immer noch unendlich! –

Antwort

6

Hier (siehe gist):

Schritt 1: Enc oding A zu erfassen ist kein Subtyp von B

trait NotSubTypeOf[A, B] 

Hinweis: Wir können Infixschreibweise verwenden A NotSubTypeOf B statt schreiben von NotSubTypeOf[A, B]

Schritt 2: Der Nachweis für zwei beliebigen beliebigen Typen A und B, A nicht ist ein Subtyp von B

implicit def isSub[A, B]: A NotSubTypeOf B = null 

Schritt 3: mehrdeutige implicits definieren Fehler im Fall A auszulösen kompilieren ist ein Subtyp von B (oder A =: = B)

Schritt 4: Definieren Sie eine type-lambda für die Negation Typ:

type Not[T] = { 
    type L[U] = U NotSubTypeOf T 
} 

Mit kind-projector kann dies viel besser lesbar gemacht werden.

Schritt 5: Fertig!

def iDontLikeStrings[A: Not[String]#L](a: A) = { 
    println(a) 
} 

iDontLikeStrings(23) // compiles 
iDontLikeStrings(true) // compiles 
//iDontLikeStrings("hello") // does not compile 

Die Compiler Fehlermeldung für die letzte Zeile in Scala 2.12, die SI-6806 Adressen besser gemacht werden.

Auch all dies ist in Shapeless integriert.