Multiple Type Parameter Lists for Type Aliases

I think Scala 3 would benefit from allowing multiple type parameter lists, at least for type aliases. I don’t know what the benefits would be if they were also allowed for functions and classes, but they would make curried types a lot easier to write. In addition to that, we might be able to write match types like this in the future (currently, there’s an error saying Homogenous[X] does not take type parameters):

type Homogenous[X][T <: Tuple] = T match {
  case EmptyTuple => EmptyTuple
  case X *: t => Homogenous[X][t]
  case _ => Nothing
}

Related discussion

Do you think that this is a necessary enough feature to add to Scala 3?

We’d like to add multiple type parameter lists for all definitions to Scala, but we anticipate that this will be a huge amount of work so it’s not something we’re planning to work on before 3.0 is out. The special case of type aliases might be easier to deal with since we already support nested type lambdas, but it’s still likely to require a lot of testing and inspection of code to make sure it works correctly. In any case, it’s already too late to get this in 3.0.

6 Likes

Does this work for you for now?

type Homogenous[X] = {
  type Apply[T <: Tuple] = T match {
    case EmptyTuple => EmptyTuple
    case X *: t => Apply[t]
    case _ => Nothing
  }
}

@main def main = 
  summon[EmptyTuple =:= Homogenous[Int]#Apply[(Int, Int)]]
1 Like

Note that the above example can use multiple type parameter lists if one curries explicitly:

type Ap[X, T <: Tuple] = T match {
  case EmptyTuple => EmptyTuple
  case X *: t => Ap[X, t]
  case _ => Nothing
}

type Homogenous[X] = [T <: Tuple] =>> Ap[X, T]

@main def main = 
  summon[EmptyTuple =:= Homogenous[Int][(Int, Int)]]
4 Likes

Yeah, that’s the workaround I ended up using. I still feel like Scala should be able to compile it with a match type inside a type lambda, though.

2 Likes