Skip to content

@retronym /not-type-constraint.scala
Created

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Simulating a subtractive type with intentionally ambiguous implicits
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 :(
@retronym
Owner

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

:)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.