1

he following compiles:

import scala.collection.mutable.MutableList

abstract class GeomBase[T <: DTypes]
{  
  val grids = new MutableList[GridBase]

  def hexs: MutableList[GridBase#HexG with T#HexTr] = grids.flatMap(_.hexs.toList)
  //the above compiles fine

  abstract class GridBase
  { 
    val hexs: MutableList[HexG with T#HexTr] = new MutableList[HexG with T#HexTr]


    class HexG(coodI: Cood) extends Hex
    {
    }
  }
}

But when I change the line from this

def hexs: MutableList[GridBase#HexG with T#HexTr] = grids.flatMap (_.hexs.toList)

to this (changing the MutableList into a List)

def hexs: List[GridBase#HexG with T#HexTr] = grids.flatMap (_.hexs.toList)

it doesn't compile any more. This doesn't compile either

def hexs: MutableList[GridBase#HexG with T#HexTr] = grids(0).hexs

It wont compile, saying I need a MutableList in the former case and type incompatibility in the latter. I don't understand why. Just to clarify in case its causing confusion HexG is an inner class of GridBase which is itself an inner class of GeomBase.

Update: Travis Brown's answer seems to provide the correct explanation for the first error. I've changed all the uses of MutableList to List. Surprisingly this not only stopped the first error but also the second. I also got errors when trying to use the types outside of the outermost GeomBase class. I got a compiler crash. when instantiating the type. Changing to Lists from MutableLists again unexpectedly removed one of these errors but not the compiler crash. I had been using Scala Eclipse plugin 2.1 special edition for 2.10.0-M3. This leads me to the conclusion that there still may be problems with the Scala compiler and path dependant types.

Rich Oliver
  • 6,001
  • 4
  • 34
  • 57

1 Answers1

2

The problem here (probably) doesn't have anything to do with the path-dependent types. Consider the following:

val xs: MutableList[Seq[Int]] = new MutableList ++ Seq(1 to 2, 3 to 4)

Now we can do the following, for example:

scala> xs.flatMap(_.toList)
res0: scala.collection.mutable.MutableList[Int] = MutableList(1, 2, 3, 4)

But a MutableList isn't a List:

scala> xs.flatMap(_.toList): List[Int]
<console>:10: error: type mismatch;
 found   : scala.collection.mutable.MutableList[Int]
 required: List[Int]
              xs.flatMap(_.toList): List[Int]

If we'd called it a Seq[Int], for example, we'd be fine, since Seq is a supertype of MutableList. List isn't (despite the name).

In your last example you're getting an error because grids(0).hexs doesn't have the right type—it's not a MutableList[GridBase#HexG with T#HexTr]. I'm not sure what it is, since you haven't shared that code with us.


As a footnote: interestingly (or maybe not), the following does work:

xs.flatMap(_.toList)(collection.breakOut): List[Int]

Don't do this, though. breakOut is weird magic.

Community
  • 1
  • 1
Travis Brown
  • 138,631
  • 12
  • 375
  • 680
  • grids(0).hexs is surely of type grid(0).HexG with T#hexTr, an instance of the projected type is it not. No relevant code is hidden. grids is actually empty, as I was just trying to get the types to match before I properly instantiated it. I don't see how using grids(n) is any different from using the whole collection. – Rich Oliver Jun 10 '12 at 20:15
  • `grids(0)` will be a `GridBase#HexG with T#HexTr`, though—not a `MutableList` of anything. – Travis Brown Jun 10 '12 at 20:17
  • grids(0) will be an instance of GridBase surely? – Rich Oliver Jun 10 '12 at 20:21
  • But grid(0).hexs is. I've explicitly declared the type now both in my IDE and in the above listing, and removed a line that was doing nothing. – Rich Oliver Jun 10 '12 at 20:32