public
Created

Simulating a subtractive type with intentionally ambiguous implicits

  • Download Gist
not-type-constraint.scala
Scala
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
trait Exclude[Scope, X]
 
object Exclude {
implicit def $$NOT_FOR_USER_CODE$$[X, A]: Exclude[X, A] = new Exclude[X, A] {}
def list[X] = new {
def apply[A] = $$NOT_FOR_USER_CODE$$[X, A]
}
}
 
sealed trait BoolOrInt
 
object BoolOrInt {
val exclude = Exclude.list[BoolOrInt]
implicit val b1, b2 = exclude[Boolean]
implicit val a1, a2 = exclude[Int]
}
 
 
def foo[T](t: T)(implicit n: Exclude[BoolOrInt, T]) = t
 
foo("") // works
foo(1) // fails!
foo(false) // fails!
foo(false)(Exclude.$$NOT_FOR_USER_CODE$$) // subverted :(
 
// Partially apply the type to be compatible with context bounds:
type Types[Scope] = {
type DoesNotContain[X] = Exclude[Scope, X]
}
 
def bar[T: Types[BoolOrInt]#DoesNotContain](t: T) = t
bar("") // works
bar(1) // fails!
bar(false) // fails!
bar(false)(Exclude.$$NOT_FOR_USER_CODE$$) // subverted :(

And duly, Mark Harrah has shown me up with some type level fancy-pants: http://github.com/harrah/up/commit/aa00b48fd1e4e141235d305e5e877fb74f076f86

:)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.