6

Taken from typelevel/kind-projector, what's the distinction between:

// partially-applied type named "IntOrA"
type IntOrA[A] = Either[Int, A]

and

// type projection implementing the same type anonymously (without a name).
({type L[A] = Either[Int, A]})#L

?

Are they equivalent?

Mario Galic
  • 47,285
  • 6
  • 56
  • 98
Kevin Meredith
  • 41,036
  • 63
  • 209
  • 384
  • What is this `#L` at the end? – Yuval Itzchakov Mar 03 '16 at 19:55
  • @YuvalItzchakov well `#L` accesses the type member that was just created inside – Łukasz Mar 03 '16 at 22:02
  • @Łukasz And what's the use of `#`? – Yuval Itzchakov Mar 03 '16 at 22:39
  • 1
    @YuvalItzchakov `#` is type projection. It allows you to access any path dependent type, which L is and treat it as not being path dependent, i.e. by path dependent types inner types are not equal when accessed with `.`, but are equal when accessed with `#`. See more http://stackoverflow.com/questions/9443004/what-does-the-operator-mean-in-scala – Teliatko Mar 04 '16 at 00:00
  • Related question [What is a kind projector](https://stackoverflow.com/q/39905267/5205022) – Mario Galic Apr 05 '20 at 14:19

1 Answers1

4

They are almost equivalent, as it is said in the comment.

Say you have a class trait Super[F[_]] {}, and you want to implement it where F[x] = Either[Int, x] You could write:

type IntOrA[A] = Either[Int, A]
class B extends Super[IntOrA] {}

But if you want a one liner, you could write:

class B extends Super[({type L[A] = Either[Int, A]})#L] {}

Or with kind-projector you could write it like:

class B extends Super[λ(A => Either[Int, A])] {}

or even:

class B extends Super[Either[Int, ?]] {}

there is no other difference than making it a one line and having this type anonymous.

Archeg
  • 8,364
  • 7
  • 43
  • 90