How to use reflection in a parameterized attribute in Scala?

Access on the manifest seems complicated out of line in scala.

How can this code compile in scala?

trait SomeTraitOf[+A] { def newInstanceOfA : A = /* necessary code to make it work */ } 

(Bound, it works fine as a parameterized class:

 class SomeTraitOf[A : Manifest] { def newInstanceOfA(implicit m : Manifest[A]) : A = m.erasure.newInstance.asInstanceOf[A] } 

but not with a covariant type parameter (+ A))

Edit: real stuff

 sealed trait RootPeerProxy[+A] extends Proxy { def peer: A def self = peer def peerManifest[B >: A](): Option[Manifest[B]] private[scalavaadin] def newInstance() : Option[A] } trait PeerProxy[+A] extends RootPeerProxy[A] { override def peerManifest[B >: A](): Option[Manifest[B]] override def peer(): A = this.newInstance match { case None => {throw new IllegalStateException("oups")} case Some(a) => a } private[scalavaadin] override def newInstance() : Option[A] = peerManifest map { m => m.erasure.newInstance.asInstanceOf[A] } } 

Since traits cannot provide a manifest for a parameterized trait, a class implementing this trait should, but I do not get it.

+4
source share
1 answer

About covariance :

Since Manifest[A] is invariant with respect to the parameter A , you cannot do what you want directly. The usual strategy is to weaken the return type,

 trait SomeTraitOf[+A] { def newInstance[B >: A](implicit m: Manifest[B]): B = { m.erasure.newInstance.asInstanceOf[B] } } 

You can use the attribute as follows:

 class Parent class Child extends Parent val childBuilder = new SomeTraitOf[Child] {} val parentBuilder: SomeTraitOf[Parent] = childBuilder parentBuilder.newInstance // returns a Parent! 

About viewing borders :

From your comment below, I think you are also asking about โ€œview restrictionsโ€, which are just a brief way of declaring an implicit parameter. Your ad

 class SomeTraitOf[A : Manifest] { ... 

basically converted to

 class SomeTraitOf[A]()(implicit m0: Manifest[A]) { .... 

Traits cannot have boundaries of the form, because they cannot take any (values) parameters. But this is not a problem because in your example

 class SomeTraitOf[A : Manifest] { def newInstanceOfA(implicit m : Manifest[A]) : A = m.erasure.newInstance.asInstanceOf[A] } 

You are not using a view restriction! (Instead, you use the m parameter.) If you want to use view binding, you can do it like this:

 class SomeTraitOf[A : Manifest] { def newInstanceOfA : A = implicitly[Manifest[A]].erasure.newInstance.asInstanceOf[A] } 
+4
source

All Articles