Coincidentally I spent a few hours trying to implement this a couple
days ago. It was harder than I hoped, but I don't see any fundamental
obstacles to it working. The visible obstacle is that it would take
me a long time to unmake the embedded assumptions about Holy AnyVal
and his Nine And Only Nine Disciples.
> On the other hand, if this construction is not going to be
> allowed, maybe we should teach the compiler that Int with Foo =:= Nothing
> and have 2.asInstanceOf[Int with Foo] throw an exception whenever Foo is an
> AnyRef.
Can't teach the compiler that because it's not true. (Maybe you meant
that less than literally.)
scala> def f[T >: Int with String] = new (T => T) { def apply(x: T) = x }
f: [T >: Int with String]=> Object with T => T
scala> f[Int](5)
res0: Int = 5
scala> f[String]("abc")
res1: String = abc
scala> f[Any]("abc")
res2: Any = abc
scala> f[List[Int]](Nil)
<console>:9: error: type arguments [List[Int]] do not conform to
method f's type parameter bounds [T >: Int with String]
f[List[Int]](Nil)
^
Types still exist even if they're uninhabited. Let's see here...
scala> def f1[T1 >: Int with String, T2 >: String with Float](x: T1
with T2)(implicit ev: T1 =:= T2) = true
f1: [T1 >: Int with String, T2 >: String with Float](x: T1 with
T2)(implicit ev: =:=[T1,T2])Boolean
scala> f1(5)
<console>:9: error: Cannot prove that Int =:= AnyVal.
f1(5)
^
scala> f1(5.0f)
<console>:9: error: Cannot prove that AnyVal =:= Float.
f1(5.0f)
^
scala> f1("abc")
res11: Boolean = true
Anyway, there are indeeed plenty of bugs in this region (there are
also tickets with commentary) and yet-to-be-properly-specified bits
even in the parts you can get at now. But I don't think fixing the
bugs would be enough to get anywhere good, we'll need better language
and compiler support.
Actually, this trick I discovered (unboxed "tagging" of types, value
types included),
https://gist.github.com/89c9b47a91017973a35f
is probably a little closer to where Jeff started from.
But certainly, like Paul, I discuss the possibility that a legal type
might be uninhabited in the unboxed union types talk.
Cheers,
Miles
--
Miles Sabin
tel: +44 7813 944 528
gtalk: mi...@milessabin.com
skype: milessabin
http://www.chuusai.com/
http://twitter.com/milessabin
Types still exist even if they're uninhabited. Let's see here...
Nope. Here are some you know are inhabited:
Int with AnyVal
Int with Any
Int with Any with AnyVal
Int with T forSome { type T >: Int }
Here's a less obvious one, illustrative of why Int being final is only
worth so much:
Int with NotNull
> (curiously I note that 1.asInstanceOf[Int with String] succeeds whereas
> 1.asInstanceOf[String with Int] throws a CCE)
Int with String erases to Int. String with Int erases to String.
Nope. Here are some you know are inhabited:
Int with AnyVal
Int with Any
Int with Any with AnyVal
Int with T forSome { type T >: Int }
Int with NotNull
Yes, "with" is not commutative. But if those examples do not satisfy
you, here is an intersection which is inhabited, which does not reduce
to Int, and which certainly can't be replaced with Nothing.
scala> def f(x: Int with Singleton) = "thank you for that very specific Int"
f: (x: Int with Singleton)String
scala> f(5)
res0: String = thank you for that very specific Int
scala> var x = 5
x: Int = 5
scala> f(x)
<console>:10: error: type mismatch;
found : Int
required: Int with Singleton
f(x)
^
You are not correct.
scala> def f(x: Int with Singleton) = "thank you for that very specific Int"
f: (x: Int with Singleton)String
scala> f(5: Int)
<console>:9: error: type mismatch;
found : Int
required: Int with Singleton
f(5: Int)
^
Or is "5: Int" not an Int value.
> Something like a mutable var x= 5 is mathematically nonsense.
I don't know about that, but it was just an example.
I don't like nitpicking, but f accepts all Int values.
Something like a mutable var x= 5 is mathematically nonsense.
Are you confusing what mathematics call integers with the type Int?
"var x" has the type Int, which makes perfect mathematical sense
(where the branch of mathematics is type theory), and which is not the
same as the type "Int with Singleton".
--
Daniel C. Sobral
I travel to the future all the time.
Except that, as noted in one of the comments on that gist, it's really
pretty useless for units of measure.
A much better application (which Jason has picked up for scalaz) is to
use it as a tagging mechanism which can drive implicit resolution (ie.
typeclass instance selection).