Scala - Lower bound inference in path-dependent types -
i'm trying understand why can't scala compiler infer following restriction on path-dependent type:
trait mytrait class mytraitimpl extends mytrait trait mytrait2[a <: mytrait] { type mytraittype = } class mytrait2impl[a <: mytrait] extends mytrait2[a] val obj: mytrait2[_] = new mytrait2impl[mytraitimpl] def mymethod[a <: mytrait](t2: mytrait2[a]) = println("hi!") mymethod[obj.mytraittype](obj) // <console>:14: error: type arguments [obj.mytraittype] not conform method mymethod's type parameter bounds [a <: mytrait] // mymethod[obj.mytraittype](obj)
for me, intuitively, mytraittype
can't other subclass of mytrait
, bound right on a
in mytrait2
. if there is, can give me example or point me code snippet wrong?
if scala compiler limitation, can show me way achieve using type system? note that:
- i not have
mytrait
object, normymethod
receive one; - i not need
mymethod
know concrete type ofa
; needs knowa
subtype ofmytrait
,t2
parametrized ona
; - the underscore in
obj
intentional; callmymethod
, don't know concrete type ofa
(or else not problem); - i prefer solutions don't have modify
mymethod
.
you should use constraints on type member instead of bounds on type parameter in mytrait2
declaration:
trait mytrait class mytraitimpl extends mytrait trait mytrait2 { // remove [a <: mytrait] type mytraittype <: mytrait // add <: mytrait } class mytrait2impl[a <: mytrait] extends mytrait2 { type mytraittype = } val obj: mytrait2 = new mytrait2impl[mytraitimpl] def mymethod[a <: mytrait](t2: mytrait2{ type mytraittype = }) = println("hi!") mymethod[obj.mytraittype](obj)
you'll compilation error on wrong types, expected:
scala> val otherobj: mytrait2 = new mytrait2impl[mytraitimpl] otherobj: mytrait2 = mytrait2impl@8afcd0c scala> mymethod[obj.mytraittype](otherobj) <console>:15: error: type mismatch; found : otherobj.type (with underlying type mytrait2) required: mytrait2{type mytraittype = obj.mytraittype} mymethod[obj.mytraittype](otherobj) ^
proof works list[mytrait2]
:
scala> { | obj <- list[mytrait2]( | new mytrait2impl[mytraitimpl], | new mytrait2impl[mytraitimpl] | ) | } mymethod[obj.mytraittype](obj) hi! hi!
Comments
Post a Comment