Scala Structural type and existential type issue -


my question in following snippet, c2 can pass compilation t2 fail. why?

  type pairt[a, b] = { //structural type     type t1 =     type t2 = b   }   class pairc[a, b] {     type t1 =     type t2 = b   } case class tmap[a, b](a: a, b: b) type mapc2[a] = tmap[p.t1, p.t2] forsome { val p: pairc[a, a] } type mapt2[a] = tmap[p.t1, p.t2] forsome { val p: pairt[a, a] }   val c2: mapc2[int] = tmap(1,2)   val t2: mapt2[int] = tmap(1,2) 

recently i've had interesting scala riddle involves existential types , type aliases (https://softwaremill.com/scala-riddle) , figured out when type alias doesn't work should try bounded abstract type members.

i haven't figured out pattern tell me kind of type member need apply in particular situation. can't find answer in documentation, maybe it's implementation detail?

i hope there me find such pattern or @ least give new clues..

how made code working

inside pairt replaced type aliases (type t1 = a) tightly bounded abstract types (type t1 >: <: a) , .. works (scalac 2.11.4).

what's more interesting - pairc, concrete class, work type aliases - if try replace them bounded abstract type members raises compilation error.

below whole code, after modifications:

package so1  import scala.language.existentials  object sopuzzle {    type pairt[f, s] = {     type t1 >: f <: f     type t2 >: s <: s   }    class pairc[f, s] {     type t1 = f     type t2 = s   }    case class tmap[t, u](a: t, b: u) {     def consumea(a: t): t =     def consumeb(b: u): u = b   }    type mapc2[a] = tmap[p.t1, p.t2] forsome {val p: pairc[a, a]}    type mapc2v2[a] = tmap[pairc[a, a]#t1, pairc[a,a]#t2]    type mapt2[a] = tmap[p.t1, p.t2] forsome {val p: pairt[a, a]}    type mapt2v2[a] = tmap[pairt[a, a]#t1, pairt[a, a]#t2]    val c2: mapc2[int] = tmap(1, 2)   val c2v2: mapc2v2[int] = tmap(1, 2)   val t2: mapt2[int] = tmap(1, 2)   val t2v2: mapt2v2[int] = tmap(1, 2)    val i1:int = c2.consumea(0)   val i2:int = c2.consumeb(0)    val i3:int = c2v2.consumea(0)   val i4:int = c2v2.consumeb(0)    val i5:int = t2.consumea(0)   val i6:int = t2.consumeb(0)    val i7:int = t2v2.consumea(0)   val i8:int = t2v2.consumeb(0) } 

Comments