Mandatory eta expansion of higher-kinded types

Are there any plans to stop requiring eta expansion of higher-kinded type bounds?

trait A
trait B[T <: A]

// Error: type B takes type parameters
def foo[C <: B]: C[A] = ???

// No error, but lots of boilerplate
def bar[C <: [T <: A] =>> B[T]]: C[A] = ???

This sort of thing used to be supported but was explicitly disallowed before 3.0: Disallow unapplied types in aliases and bounds by odersky · Pull Request #9090 · lampepfl/dotty · GitHub

For the record, it’s possible to write this slightly more concisely:

def bar[C[T <: A] <: B[T]]: C[A] = ???
2 Likes

Thanks! I would never have thought of adding a seemingly unbound T like that.

Is there anywhere in the documentation where I can add such an example?

1 Like

Right now this is documented both in the spec, section 4.3.1 and in the Scala 3 “Type Lambdas - More Details” page. It seems we’re missing a high-level doc page dedicated to higher-kinded types where this sort of things could also be mentioned, so I’m not sure there’s any good place to add such an example right now.

1 Like

I cannot actually see it documented in either of the links you shared. I’m not implying your links are bad; I’m probably just not looking properly, but below I describe what I see.

The page from the first link says

Scala has several other advanced types that are not shown in this book, including:
…

  • Higher-kinded types

, which seems to imply it is not documented in the book. I also tried to follow the link at the bottom of that page, to the Scala 3 Reference (Is that the spec?), but I don’t see any section numbers on that page, and higher-kinded types are only mentioned once, without any actual documentation that I can see.

Concerning the second link, the part most closely resembling documentation I could find is

A partially applied type constructor such as List is assumed to be equivalent to its eta expansion. I.e, List = [X] =>> List[X].

, which seems to almost imply the opposite, namely that there should be no distinction between a higher-kinded type and its eta expansion.

Sorry if I’m being dense! In that case, feel free to ignore my message.

The spec link was wrong. It was meant to point to
https://www.scala-lang.org/files/archive/spec/3.4/04-basic-definitions.html#desugaring-of-parameterized-type-definitions

2 Likes

And I see now that I did in fact not look properly at the second link. I just found this part:

The same expansions apply to type parameters. For instance,

[F[X] <: Coll[X]]

is treated as a shorthand for

[F >: Nothing <: [X] =>> Coll[X]]