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

Popular posts from this blog

sql - VB.NET Operand type clash: date is incompatible with int error -

SVG stroke-linecap doesn't work for circles in Firefox? -

python - TypeError: Scalar value for argument 'color' is not numeric in openCV -