Is it possible to have a manifest defined based on another manifest in Scala? -
is possible have manifest defined based on manifest in scala?
i've pretty resigned myself belief not possible because scala manifest information not intended used dynamically.
here's problem. have function can return more 1 type of object (string, int, list[int], list[list[string]], etc.) support these multiple types, return type set any, due type erasure information types supported in lists, maps, etc lost. in attempt recover of details, return manifest along return type.
however, returned information may placed in list or map , returned function. want update manifest include fact type list or map of previous type defined manifest.
here's example code
def returnwithmanifest[t: manifest](x: t) = (x, manifest[t]) // may return string, int, list[int], list[list[string]], ... def contrivedexample(t: string): (any, manifest[_]) = t match { case "string" => returnwithmanifest("test") case "int" => returnwithmanifest(1) case "boolean" => returnwithmanifest(true) case "list[int]" => returnwithmanifest(list(1,2,3)) case "list[list[string]]" => returnwithmanifest(list(list("a","b"),list("c","d"))) case _ => returnwithmanifest(none) } scala> val v1 = contrivedexample("list[int]") v1: (any, manifest[_]) = (list(1, 2, 3),scala.collection.immutable.list[int]) scala> val x = v1._1 x: = list(1, 2, 3) scala> val m = v1._2 m: scala.reflect.manifest[_] = scala.collection.immutable.list[int] scala> val v2 = list(x) v2: list[any] = list(list(1, 2, 3)) from manifest of 'v1' know v1 of type list[int] when create 'v2' should have information need create manifest identifying type list[list[int]], instead have list[any] work with. perhaps syntax following:
val v2: m = list(x) val v2 = list[m](x) i realize looks i'm trying define type dynamically, in reality information metadata related type erasure of statically known types. guess if can solved, type erasure can solved. however, @ least thought should able like:
scala> val m2 = m.wrapinlist() m2: scala.reflect.manifest[_] = scala.collection.immutable.list[scala.collection.immutable.list[int]]
edit: adriaan moors right pointing out works:
def makelistmanifest[t: manifest] = manifest[list[t]] you'll have call explicitly, passing manifest have obtained.
my old answer:
huynhjl partially right: won't work automatically. we'd need compiler smart enough compile this:
def makelistmanifest[t](m: manifest[t]) = manifest[list[t]] without implicit parameter. while looks feasible (all needed info here), isn't implemented yet (2.9.0.1), believe manifests either inserted locally if compiler has static type info needs or looked in implicit scope, not generated other (possibly implicitly available) manifests.
what can do, however, construct manifest methods on companion object:
scala> import reflect.manifest scala> manifest.classtype(classof[list[_]], manifest[int]) res0: scala.reflect.manifest[list[_]] = scala.collection.immutable.list[int] so can implement makelistmanifest yourself:
scala> def makelistmanifest[t](m: manifest[t]) = manifest.classtype(classof[list[_]], m) makelistmanifest: [t](m: scala.reflect.manifest[t])scala.reflect.manifest[list[_]] note although right manifest returned, static return type of makelistmanifest manifest[list[_]]. safely cast manifest[list[t]] here.
Comments
Post a Comment