Either
is right-biased ince Scala 2.12 which allows it to be used in for/yield blocks without projection just like Option
. But apparently this isn't enough to behave like Option
when used with flatMap
.
object Main {
def main(args: Array[String]): Unit = {
val nums = List.range(1,10)
println(nums.flatMap(evenOption))
println(nums.flatMap(evenEither)) // fails
}
def evenOption(x: Int): Option[Int] = if (x % 2 == 0) Some(x) else None
def evenEither(x: Int): Either[String, Int] = if (x % 2 == 0) Right(x) else Left("not even")
}
My minimal category theory knowledge makes me think that Either
is not a monad and therefore this fails? Or how else can I make the example above work?
It has nothing to do with Either being or not being a monad. When you're executing flatMap
method on some data structure, the function that you're passing into has to return an instance of that data structure. So when you're flatmapping over an Option, your function has to return an Option. If you're flatmapping over a Future, your function has to return a Future. The same goes with a List: flatmapping over a list has to return a List itself. So why does your List.flatMap(Option)
work and List.flatMap(Either)
doesn't? Because there's an implicit conversion from an Option to an Iterable (Option.option2Iterable
), and that conversion took place in your example. There's no such conversion for the Either datatype (unless you create it yourself).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With