【问题标题】:Scala - Is there a function to map Seq[A] => Seq[Either[Throwable, B]]?Scala - 是否有映射 Seq[A] => Seq[Either[Throwable, B]] 的函数?
【发布时间】:2018-11-07 17:59:10
【问题描述】:

我正在寻找一个函数,该函数将映射集合 coll: Seq[A],同时应用函数 f: A => B 并返回 Seq[Either[Throwable, B]],以便可以在下游处理错误。

是否有类似的功能预烘焙到某个库中?也许是 Cats 或 Scalaz?

在下面查看我的实现:

import cats.syntax.either._

def eitherMap[A,B](f: A => B, coll: Seq[A]): Seq[Either[Throwable, B]] = {
  coll.map { elem => 
      Either.catchNonFatal(f(elem))
  }
}

【问题讨论】:

  • 你真的需要Either吗?看起来Try 会这样做:coll.map(a => Try(f(a)))
  • 如果你真的需要Eithercoll.map(a => Try(f(a)).toEither)
  • 这样的功能对我来说似乎太具体了。顺便说一句,看到一个带有A => B 的签名然后不知何故神奇地变成了响应中的一个,感觉有点奇怪。我宁愿将A => Either[Throwable, B]] 作为参数,并将f andThen Either.catchNonFatal 传递给它。

标签: scala scalaz scala-cats map-function either


【解决方案1】:

Per jwvh: coll.map(a => Try(f(a)).toEither) 似乎是完成此任务的最简单/最干净的方法。

【讨论】:

    【解决方案2】:

    不幸的是,我不相信您正在寻找的东西已经完全存在...但是这是一个通用实现,可以满足您的需求,也许进一步阅读 cat 中的 ApplicativeError 类型类会让您更接近

    type ErrorOr[A] = Either[Throwable, A]
    
    object MapAttempt {
      implicit class MapAttemptOps[A, F[_] : Functor](fa: F[A]) {
        def mapAttempt[B, G[_]](f: A => B)(implicit appErr: ApplicativeError[G, Throwable]): F[G[B]] =
          fa.map(a => appErr.catchNonFatal(f(a)))
      }
    }
    
    import MapAttempt._
    
    List(0, 1, 2, 3, 4).mapAttempt[Int, ErrorOr](5 / _)    
    

    返回:

    res0: List[ErrorOr[Int]] = List(Left(java.lang.ArithmeticException: / 零),右(5),右(2),右(1),右(1))

    编辑:特征和语法的分离不是必需的,所以我删除了它

    【讨论】:

    • List(0, 1, 2, 3, 4).map(n => util.Try(5/n).toEither)
    猜你喜欢
    • 2019-09-23
    • 2011-11-06
    • 1970-01-01
    • 2020-07-16
    • 2012-10-11
    • 1970-01-01
    • 2015-12-08
    • 2010-11-12
    • 1970-01-01
    相关资源
    最近更新 更多