I’ve seen in several places that when using the Either
type, right is right and left is wrong. Is the expectation really that Either
is used for right/wrong situations. If I have a situation where a function needs to return one of two perfectly good results with different semantics, should I implement my own class isomorphic to Either
to avoid this confusion? Or what is the recommendation?
Either
originally wasn’t right-biased until 2.12, i.e. most methods like map
, flatMap
, etc. weren’t defined on Either
directly, but only on the left and right projections. As error handling with Left
for errors is the most common usecase, the right-bias was introduced, but it’s perfectly valid to have Left
and Right
both contain valid outcomes. Even the first example in the documentation doesn’t use it for error handling.
Side note: Dotty / Scala 3 will have union types built in, which solves the same problem, but better integrated into the type system (for example, A
will be a subtype of A | B
)
BTW, I’m really looking forward to union types in Scala. But as I understand, dotty chose not to implement intersection and complement types. Right? Intersection, complement, and union types are one of the fun features of the Common Lisp type system, which is unfortunately not integrated into the object system. Scala features which I’ve always wanted in lisp are especially exciting.
Dotty has intersection types. I haven’t heard about complement types yet, what would they do? Allowing to specify something like "anything except some type A
"?
Dotty has:
- union types: https://dotty.epfl.ch/docs/reference/new-types/union-types.html
- intersection types: https://dotty.epfl.ch/docs/reference/new-types/intersection-types.html
- and some weird Not class which maybe can be used in some cases for emulating complement types: https://dotty.epfl.ch/api/scala/implicits/Not.html
The most common use of complement types, at least in lisp, is in conjunction with intersection to implement and-not types. So such as (and integer (not bignum))
, (and array (not vector))
, or (and rational (not (eql 0)))
.