0
class Outter {
  type Inner = Either[Int, String]

  def f(x: this.Inner) = 1
}

val o = new Outter
val someLeft = Left(1)
o.f(someLeft)

tried at the REPL:

scala> :load Learn.scala
Loading Learn.scala...
defined class Outter
o: Outter = Outter@28037ced
someLeft: scala.util.Left[Int,Nothing] = Left(1)
res0: Int = 1

Which confuses the hell out of me as Outter.f() has an explicit path-dependent type argument (x: this.Inner) which means only those Lefts (or Rights) that are (a sub-type of) o.Inner are allowed and not just any Left[Int,_] or Right[Int,_]. I expect to see a type mismatch error along the lines :

Required o.Inner, Found Left[Int,Nothing].

But it just compiles fine! What am I (badly) missing here ?

Ashkan Kh. Nazary
  • 21,844
  • 13
  • 44
  • 68

1 Answers1

3

type Inner = Either[Int, String] is just a type alias. This is the expected behavior.

only those Lefts (or Rights) that are (a sub-type of) o.Inner are allowed and not just any Left[Int, _] or Right[Int, _].

There is only one Left and one Right class, respectively. There are no Lefts or Rights that are only a sub-type of o.Inner and nothing else. Creating a type alias does not create a new type that belongs only to class Outter. The only thing that is unique to Outter is the alias name Inner, but Either is the same old scala.util.Either.

Michael Zajac
  • 55,144
  • 7
  • 113
  • 138
  • Then there is no way of creating path-dependent types from the types already defined ? – Ashkan Kh. Nazary Feb 22 '16 at 15:49
  • I believe I'm severely off the charts here :D – Ashkan Kh. Nazary Feb 22 '16 at 15:50
  • Not exactly. You might try wrapping the types, instead? I'm not sure why you'd want something like this. – Michael Zajac Feb 22 '16 at 15:51
  • I was under the impression that the `type` alias would spare me the hassle of (re)implementing an `Either` that depends on the enclosing value (i.e. path-dependent). Now I understand `type` is just an alias = nothing to do with the enclosing object. How do I achieve the "wrapping" then ? as `Either` is sealed ... – Ashkan Kh. Nazary Feb 22 '16 at 15:56
  • 1
    Why not create a case class containing the either `case class Inner(inner: Either[Int, String])` – Pim Verkerk Feb 22 '16 at 15:58
  • The first answer here looks like something you could use http://stackoverflow.com/questions/2693067/what-is-meant-by-scalas-path-dependent-types – Pim Verkerk Feb 22 '16 at 16:06
  • @m-z and Pim (apparently can't @-mention you :( ) , kindly take a look at follow-up question http://stackoverflow.com/q/35558342/369489 – Ashkan Kh. Nazary Feb 22 '16 at 16:08
  • @PimVerkerk yeah I have been through that already. Many times, actually. But apparently there is something big I have managed to miss here :-). Take a look at my follow-up though. That's what I'm trying to achieve here. – Ashkan Kh. Nazary Feb 22 '16 at 16:10