How to define an existential higher type type in Scala

I tried to define a type that accepts an existential higher type type in Scala.

Unfortunately, Scalac does not allow this.

Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_45). Type in expressions to have them evaluated. Type :help for more information. scala> :paste // Entering paste mode (ctrl-D to finish) trait H[F[_, _]] trait T[A, B] val h:H[T] = null val e:H[F] forSome { type F[A, B] } = h // Exiting paste mode, now interpreting. <console>:13: error: type mismatch; found : H[T] required: H[_[A, B] <: Any] Note: T <: Any, but trait H is invariant in type F. You may wish to define F as +F instead. (SLS 4.5) val e:H[F] forSome { type F[A, B] } = h ^ 

How can I get along?

How can I determine a type that matches any H regardless of the type parameter?

Update: I even tried to let Scalac infer the existential type, still no luck.

 Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_45). Type in expressions to have them evaluated. Type :help for more information. scala> :paste // Entering paste mode (ctrl-D to finish) trait H[F[_, _]] trait T[A, B] val h:H[T] = null trait T2[A, B] val h2:H[T2] = null Seq(h, h2) // Exiting paste mode, now interpreting. <console>:17: error: type mismatch; found : H[T] required: H[_ >: T2 with T <: Object] Seq(h, h2) ^ <console>:17: error: type mismatch; found : H[T2] required: H[_ >: T2 with T <: Object] Seq(h, h2) ^ 
+5
source share
3 answers

Probably sschaef is right, this is impossible. I do not know if the following will help you:

 type F[A,B] = X[A,B] forSome { type X[A,B] } // alias trait H[F[_, _]] trait T[A, B] val h: H[T] = null val e: H[F] = h.asInstanceOf[H[F]] 
0
source

I found that higher order existential types can be written in type templates (and deduced from there):

 def toExistential[F[_, _]](h: H[F]) = h.asInstanceOf[Any] match { case x: H[_] => x } > val h = new H[T] {} h: H[T] = $anon$1@4d0c3eac > val f = toExistential(h) f: H[_] = $anon$1@4d0c3eac 

The cast to Any seems necessary, but at least it can be encapsulated in a function.

0
source

Instead of a type parameter, you can use a type member:

 trait H { type F[_, _] } 
0
source

All Articles