How can I use the negation type in Scala?

I want to do something like this:

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

Basically, this should compile:

iDontLikeStrings(23) 
iDontLikeStrings(true)

And this should NOT compile:

iDontLikeStrings("hello") 
+4
source share
1 answer

Here is my implementation (see gist ):

Step 1: Encoding for Capture A is not a subtype of B

trait NotSubTypeOf[A, B] 

Note. We can use infix notation for writing A NotSubTypeOf BinsteadNotSubTypeOf[A, B]

Step 2: The proof for any two arbitrary types A and B, A is not a subtype of B

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

Step 3: Define ambiguous implications to trigger a compilation error when A is a subtype of B (or A =: = B)

implicit def iSubAmbig1[A, B >: A]: A NotSubTypeOf B = null
implicit def iSubAmbig2[A, B >: A]: A NotSubTypeOf B = null

Step 4: Define type-lambda for the negation type:

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

kind-projector .

5: !

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

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

Scala 2.12, SI-6806.

, Shapeless.

+6

All Articles