How to use a wildcard for a higher type in Scala?

Say I have this trait

trait Ctx[C, V[_]] 

I cannot build any method signature that accepts Ctx, of which the parameter of the second type is not specified (wildcard). For example. this is:

 def test(c: Ctx[_, _]) = () 

does not compile ( "error: _$2 takes no type parameters, expected: one" ). I also can not do

 def test(c: Ctx[_, _[_]]) = () 

( "error: _$2 does not take type parameters" ). What am I missing?

+6
scala wildcard
source share
3 answers

I can define this:

 def test[V[X]](c:Ctx[_,V]) {} 

And it seems to work fine with the output type:

 scala> trait Ctx[ C, V[ _ ]] defined trait Ctx scala> def test[V[X]](c:Ctx[_,V]) {} test: [V[X]](c: Ctx[_, V])Unit scala> class P extends Ctx[Int, List] defined class P scala> new P res0: P = P@1f49969 scala> test(res0) 

Change I suspect that replacing the Ctx tag Ctx not practical to use an abstract type, but this is what I was able to do:

 trait Ctx[C] { type V[X] } class CtxOption[C] extends Ctx[C] { type V[X] = Option[X] } class CtxList[C] extends Ctx[C] { type V[X] = List[X] } def test(ctx:Ctx[_]) { println(ctx) } val ctxOptInt = new CtxOption[Int] val ctxListStr = new CtxList[String] test(ctxOptInt) test(ctxListStr) val list = collection.mutable.ListBuffer[Ctx[_]]() list += ctxOptInt list += ctxListStr list 

Using an abstract type for V-parts is a difficult (or impossible) task to determine the type parameter syntax for a wildcard type constructor. In addition, as shown in the ListBuffer example, you can handle objects where V is another type constructor (option and list in my example). The first solution I provided will not allow you to do this.

Edit 2 : How about?

 trait AbstractCtx[C] { type W[X] } trait Ctx[C,V[_]] extends AbstractCtx[C] { type W[X] = V[X] } def test(ctx:AbstractCtx[_]) { println(ctx) } 
+5
source share

You need to pass a type constructor for the second argument to Ctx . Scala cannot infer the correct type if you just pass _ . It is also impossible to define a type constructor with wildcards (that is, _[_]] β€œon the fly.” Note that in the first _$2 example, the error message indicates the type passed as the second argument to Ctx as a whole. Second example, however, _$2 is the first wildcard type in _[_] . See the location indicator in error messages:

 <console>:6: error: _$2 does not take type parameters def test( c: Ctx[ _, _[ _ ]]) {} ^ 

The following works, since here V is a constructor of the type of the correct type expected by Ctx .

 def test[V[_]]( c: Ctx[ _, V]) {} 
+3
source share

Everything is explained here . Focus on the "Common Traps" section below.

-one
source share

All Articles