在Scala的List [Either]中使用flatMap [英] Use flatMap on List[Either] in Scala

查看:117
本文介绍了在Scala的List [Either]中使用flatMap的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

或者是正确的偏向因子Scala 2.12,它允许它用于没有投影的for / yield块,就像 Option 。但显然,这与用于 flatMap 的行为类似 Option

  object main {

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)

}
pre>

我最小的类别理论知识让我认为或者不是单子,因此失败了吗?或者我怎么能让上面的例子工作呢?

解决方案

无论是否成为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 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).

这篇关于在Scala的List [Either]中使用flatMap的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆