在Scala的List [Either]中使用flatMap [英] Use flatMap on List[Either] in Scala
问题描述
Option
。但显然,这与用于 flatMap
的行为类似 Option
。object main {
pre>
def main(args:Array [String]):Unit = {
val nums = List.range(1,10)
println(nums.flatMap(evenOption))
println(nums.flatMap(evenEither))//失败
)
def evenOption(x:Int):Option [Int] = if(x%2 == 0)Some(x)else None
def evenEither(x:Int):或者[String,Int] = if(x%2 == 0)Right(x)else Left(not even)
}
我最小的类别理论知识让我认为
或者
不是单子,因此失败了吗?或者我怎么能让上面的例子工作呢?解决方案无论是否成为monad都无关紧要。在某些数据结构上执行
flatMap
方法时,您传入的函数必须返回该数据结构的一个实例。所以当你在一个选项上平面图时,你的函数必须返回一个选项。如果你正在为未来打平,你的功能必须返回一个未来。列表也是如此:列表上的平面映射必须返回列表本身。那么为什么你的List.flatMap(Option)
工作并且List.flatMap(或者)
不?因为有一个从Option到Iterable的隐式转换(Option.option2Iterable
),并且该转换发生在您的示例中。对于任何一种数据类型都没有这种转换(除非您自己创建它)。
Either
is right-biased ince Scala 2.12 which allows it to be used in for/yield blocks without projection just likeOption
. But apparently this isn't enough to behave likeOption
when used withflatMap
.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 yourList.flatMap(Option)
work andList.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).这篇关于在Scala的List [Either]中使用flatMap的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!