Я хочу сделать что-то вроде этого:
def iDontLikeStrings(arg: Not[String]) = {....}
В принципе, это должно скомпилироваться:
iDontLikeStrings(23)
iDontLikeStrings(true)
И это НЕ должно компилироваться:
iDontLikeStrings("hello")
Я хочу сделать что-то вроде этого:
def iDontLikeStrings(arg: Not[String]) = {....}
В принципе, это должно скомпилироваться:
iDontLikeStrings(23)
iDontLikeStrings(true)
И это НЕ должно компилироваться:
iDontLikeStrings("hello")
Вот моя реализация (см. суть):
Шаг 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.
Any
:) - person pathikrit   schedule 11.04.2016