Scala: How to Pattern Match a Union of Parameterized Types -
i using rex kerr's variant of miles sabin's idea implementing unboxed union types in scala. have following class:
class foo[t] { trait contr[-a] {} type union[a,b] = {type check[z] = contr[contr[z]] <:< contr[contr[a] contr[b]]} def foo[u: union[t,foo[t]]#check](x:u) = x match { case _: foo[t] => println("x foo[t]") case _: t @unchecked => println("x t") } }
this allows following:
val aux = new foo[int] aux.foo(aux) // prints "x foo[t]" aux.foo(42) // prints "x t" aux.foo("bar") // not compile
however:
val bar = new foo[foo[int]] bar.foo(bar) // ok: prints "x foo[t]" bar.foo(aux) // not ok: prints "x foo[t]"
is there way fix this, , maybe eliminate @unchecked
?
edit think union
type, particular example, can simplified to:
type union[z] = contr[contr[z]] <:< contr[contr[t] contr[foo[t]]]
and foo function can be:
def foo[u: union](x:u) = ...
this makes code simpler. however, issue remains.
i have come following, seems work, , closer real use case:
import scala.reflect.runtime.universe._ case class foo[t](z:t)(implicit tt:typetag[t], ft:typetag[foo[t]]) { trait contr[-a] type union[z] = contr[contr[z]] <:< contr[contr[t] contr[foo[t]]] def foo[u: union](x:u)(implicit tu:typetag[u]):t = tu.tpe match { case t if t =:= tt.tpe => x.asinstanceof[t] case t if t =:= ft.tpe => x.asinstanceof[foo[t]].z } }
now, following works well:
val aux = new foo[int](42) val bar = new foo[int](7) val foobar = new foo[foo[int]](bar) println(aux.foo(aux)) // 42 println(aux.foo(1)) // 1 println(foobar.foo(aux)) // foo(42) println(foobar.foo(foobar)) // foo(7)
i nice rid of x.asinstanceof
, though.
Comments
Post a Comment