How to cast Any to Array[T] maintaining Scala's invariance for arrays -
i tried implement following function maintaining scala's invariant view on jvm arrays:
def cast[t](a: any): option[array[t]] = ???
that is, given:
class foo class bar extends foo
i want following examples return some
:
val arr1: = array(new bar) cast[bar](arr1) // ok val arr2: = array(1, 2, 3) cast[int](arr2) // ok val arr3: = array("a", "b", "c") cast[string](arr3) // ok
for following one, instead, want return none:
val arr: = array(new bar) cast[foo](arr1) // want none val arr2: = array(list(new bar)) cast[list[foo]](arr2) // must none too!
i tried through reflection using classtag/typetag
no luck, since i'm no reflection expert missing something.
p.s.: know having any
there, bad practice but, please, try see question academically. know, find out if there's way , how to.
update: solution provided below still not work array(list(new bar))
because of type erasure.
i think after:
import scala.reflect.classtag def cast[t](a: any)(implicit ct: classtag[array[t]]): option[array[t]] = ct.unapply(a)
in repl:
scala> val x: = array(1, 2, 3) x: = array(1, 2, 3) scala> val y = cast[int](x) y: option[array[int]] = some([i@7a8f55c) scala> val z = cast[string](x) z: option[array[string]] = none
the solution above doesn't keep invariance; best way found far this:
def cast[t](in: any)(implicit ct: classtag[array[t]]): option[array[t]] = if (ct.runtimeclass == in.getclass) ct.unapply(in) else none
not sure how nice works:
scala> :paste // entering paste mode (ctrl-d finish) class foo class bar extends foo val x: = array(new bar) val y = cast[foo](x) val z = cast[bar](x) // exiting paste mode, interpreting. defined class foo defined class bar x: = array(bar@6109a8cc) y: option[array[foo]] = none z: option[array[bar]] = some([lbar;@7ccebaae)
Comments
Post a Comment