Nicer syntax for inductive coproducts
Currently, tuples can be manipulated as an inductive data structure (Unit being the terminal type, and *: the cons type). This is extremely useful for generic programming. It is worth noting that the Scala 2 user-facing syntax for tuples is still available:
(Int, String) =:= Int *: String *: Unit
Thus, end-users can use the familiar tuple syntax, but library authors can implement powerful data-type generic computations in terms of the inductive representation of tuples.
However, it is well known that we live in a world of dualities.
So, how does the developer experience look like for manipulating coproducts? Inductive coproducts can be represented with Nothing for the terminal type and Either for the cons type:
Either[A, Either[B, Nothing]]
Library authors can implement powerful data-type generic computations in terms of this inductive representation of coproducts.
However, end-users don’t have a nice syntax to work with. They have to carry these nested Either types. What about introducing the following syntax?
A ^ B =:= Either[A, Either[B, Nothing]]
We also need a corresponding term-level syntax for constructing and extracting A ^ B values:
val coproduct: Int ^ String = left(42)
coproduct match {
case left(int) => ...
case right(string) => ...
}
There is probably room for improvement here: unlike with tuples, the term-level syntax is not symmetric with the type-level syntax.
IMO in your example:
Nothingshould be in theLeftposition, sinceRightsounds like the "value"case Right(string) => ...is actuallycase Right(Left(string)) => ...
Currently, you can express something very close to what you are asking for
scala> type ^[L,R] = L Either R
// defined alias type ^[L, R] = Either[L, R]
scala> val nested: Int ^ String ^ Double ^ Boolean ^ Exception = Left(Left(Left(Right("yay!"))))
val nested:
Either[Either[Either[Either[Int, String], Double], Boolean], Exception] = Left(Left(Left(Right(yay!))))