Как я могу иметь тип отрицания в Scala?

Я хочу сделать что-то вроде этого:

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

В принципе, это должно скомпилироваться:

iDontLikeStrings(23) 
iDontLikeStrings(true)

И это НЕ должно компилироваться:

iDontLikeStrings("hello") 

person pathikrit    schedule 10.04.2016    source источник
comment
Просто любопытно, можете ли вы привести практический пример, когда вы бы использовали это?   -  person Chris Martin    schedule 11.04.2016
comment
Почти никогда - тип отрицания на один крошечный шаг выше Any :)   -  person pathikrit    schedule 11.04.2016
comment
Не уверен, что это даже шаг - Бесконечность минус один все равно бесконечность!   -  person Chris Martin    schedule 11.04.2016
comment
@ChrisMartin: Что-то вроде этого: ` trait Sensitive // ​​маркер признака для любого класса, содержащего конфиденциальную информацию def sendToUser (a: Not [Sensitive]) `   -  person pathikrit    schedule 11.04.2016


Ответы (1)


Вот моя реализация (см. суть):

Шаг 1: Кодирование для захвата A не является подтипом B

trait NotSubTypeOf[A, B] 

Примечание. Мы можем использовать инфиксную нотацию для записи A NotSubTypeOf B вместо NotSubTypeOf[A, B].

Шаг 2: Доказательство для любых двух произвольных типов A и B, A не является подтипом B

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

Шаг 3: Определите неоднозначные имплициты, чтобы вызвать ошибку компиляции в случае, если A является подтипом B (или A =:= B)

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

Шаг 4. Определите type-lambda для типа отрицания:

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.

person pathikrit    schedule 10.04.2016