Basically, I'd like to be able to write something like this:
val x :('k1.type, Int) = 'k1 -> 1
val y :('k2.type, Int) = 'k2 -> 2
Where types of x and y are not compatible, but either share a super type or can be annotated with context bounds, allowing me to do something like this:
def mlt[T :MyLittleType](x :(T, Int)) = ???
mlt(x); mlt(y)
Keywords are used here only as an example, the goal is to be able to provide both literals and singleton types for some identifiers/keywords/strings. The types might as well get erased/unified in runtime, I am interested only in static type check. I guess it should be possible to attain this using macros, but I would rather not.
You can construct structural types inline:
So, you can combine them with objects to give them type uniqueness:
Or (little bit slower beacause of reflection)
You can combine it with tags to annotate your type like:
More tagging examples:
So, you can:
Or just use:
You may operate
x
as bothInt
usingTag.unwrap(x)
, or just defineimplicit def t[T] = Tag.unwrap[Int, T] _
to make no difference between Tag and Int, but be careful here - any non-tag oriented function will remove the tag)Another inline type constructor solutions:
a) ugly
b) funny: