|
| 1 | +--- |
| 2 | +layout: sip |
| 3 | +disqus: true |
| 4 | +title: SIP-20 Fixing Either's for-comprehension behaviour |
| 5 | +--- |
| 6 | + |
| 7 | +**By: Rob Dickens** |
| 8 | + |
| 9 | +## Motivation ## |
| 10 | + |
| 11 | +There is [evidence][evidence] to suggest that `scala.Either` is being |
| 12 | +eschewed in favour of alternatives such as Scalaz's `Validation` |
| 13 | +class. Based on this, together with a subsequent study which resulted in |
| 14 | +[this suggestion][suggestion], the following three reasons may be |
| 15 | +considered likely. |
| 16 | + |
| 17 | +1. The alternatives are simpler to use, since they are 'biased' |
| 18 | + towards one of their two possible types of result - in the case of |
| 19 | + `Either`, it is necessary to specify that it's the `Left` (or |
| 20 | + `Right`) instance whose value will be passed to `foreach`, `map` or |
| 21 | + `flatMap`. |
| 22 | + |
| 23 | +2. `for` comprehensions involving `Either` do not always behave as |
| 24 | + expected! |
| 25 | + |
| 26 | +3. The alternative may offer 'added value', such as `Validation`'s |
| 27 | + ability to accumulate failures. |
| 28 | + |
| 29 | +The current SIP is a proposal to address reason 2. only. (It may also |
| 30 | +be considered a proposal to leave `Either` unbiased, on the grounds that |
| 31 | +its name does not imply any bias towards either of it's subtypes.) |
| 32 | + |
| 33 | +The aforementioned study traced the unexpected behaviour in |
| 34 | +`for` comprehensions to two specific aspects of the API of `Either`'s |
| 35 | +`Left/RightProjection` inner classes, and the two corrections that were |
| 36 | +[suggested][suggestion] are now being proposed here. |
| 37 | + |
| 38 | +## 1. map should return a Left/RightProjection instead of an Either ## |
| 39 | + |
| 40 | +Returning an `Either` means that definitions in `for` comprehensions are |
| 41 | +not supported, since `Either` does not have a `map` method. Instead, |
| 42 | +`map` should return a `Left/RightProjection`, which does have a `map` method, |
| 43 | +together with a `foreach` and `flatMap`. |
| 44 | + |
| 45 | +## 2. filter should be removed ## |
| 46 | + |
| 47 | +This is not appropriate, since an empty result is not appropriate here |
| 48 | +- either it's a `Left` or it's a `Right`. |
| 49 | + |
| 50 | +If the, say, `Right` value in question is to be subject to a |
| 51 | +condition, then it should first be transformed into a `scala.Option`, |
| 52 | +using an `R => Option[R]` (for use with `map`) or `R => Either[L, |
| 53 | +Option[R]]` (for use with `flatMap`), so as to retain the opportunity of |
| 54 | +handling a `Left` result. |
| 55 | + |
| 56 | + [evidence]: http://robsscala.blogspot.co.uk/2012/04/validation-without-scalaz.html |
| 57 | + [suggestion]: |
| 58 | + http://robsscala.blogspot.co.uk/2012/05/fixing-scalaeither-leftrightmap-returns.html |
0 commit comments