Skip to content

Instantly share code, notes, and snippets.

@milessabin
Created September 19, 2011 16:44
Show Gist options
  • Save milessabin/de58f3ba7024d51dcc1a to your computer and use it in GitHub Desktop.
Save milessabin/de58f3ba7024d51dcc1a to your computer and use it in GitHub Desktop.
No Nothings
def unexpected : Nothing = sys.error("Unexpected invocation")
// Encoding for "A is not a subtype of B"
trait <:!<[A, B]
// Uses ambiguity to rule out the cases we're trying to exclude
implicit def nsub[A, B] : A <:!< B = null
implicit def nsubAmbig1[A, B >: A] : A <:!< B = unexpected
implicit def nsubAmbig2[A, B >: A] : A <:!< B = unexpected
// Type alias for context bound
type |¬|[T] = {
type λ[U] = U <:!< T
}
def something[T: |¬|[Nothing]#λ](t : T) = t
val smth1 = something(23) // OK
val smth2 = something("foo") // OK
val smth3 = something(error("Boom!")) // Does not compile
@rkuhn
Copy link

rkuhn commented Sep 19, 2011

why exactly is this not in the standard library?

@andyczerwonka
Copy link

wow... I didn't think it was possible...

@deanwampler
Copy link

Nice.

It looks like you can replace with |¬| with just ¬. Any particular reason for the bars?

@epiphyllum
Copy link

implicit def nsubAmbig1[A, B >: A] : A <:!< B = unexpected
implicit def nsubAmbig2[A, B >: A] : A <:!< B = unexpected

why this duplication?

@vhutov
Copy link

vhutov commented Dec 12, 2019

@epiphyllum because otherwise, this trick doesn't work 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment