Open julienrf opened 5 years ago
IMO in your example:
Nothing
should be in the Left
position, since Right
sounds like the "value"case Right(string) => ...
is actually case 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!))))
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: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 andEither
for the cons type: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?We also need a corresponding term-level syntax for constructing and extracting
A ^ B
values:There is probably room for improvement here: unlike with tuples, the term-level syntax is not symmetric with the type-level syntax.