Scalaz在错误和成功方面都有积累的东西吗?

时间:2012-08-10 14:39:39

标签: scala monads fold scalaz applicative

我开始使用Scalaz 7 Validation和/或disjunction处理可能失败的操作列表并管理其结果。

对于这种用例,有两个记录良好的案例:

1 /您想检查某些条件的列表,并累积每个错误(如果有的话)。在这里,你总是走到列表的末尾,如果有任何错误,你就会失败作为全局结果。 这是一个适用于工作的应用程序。

2 /您想要执行可能失败的几个步骤,并在第一个失败时停止。 在这里,我们有一个单调,在Scala中很好地理解。

所以,我有两个在同一行中的其他用例,但似乎在任何先例都不是很好: 我想处理一个步骤列表,可能会失败,并累积错误和成功结果(例如:它是文件修改列表,错误可能发生,因为那是外部世界,成功是我想要保留的补丁)。

两个用例的区别仅在于我想提前停止(在第一个错误上)或者到列表的末尾。

好的,那对此是什么意思?

(写这个问题让我觉得它只是一个简单的foldLeft,是吗?我会让这里的问题验证,如果有人想知道的话)

4 个答案:

答案 0 :(得分:5)

查看Validation#append或其别名Validation#+|+。给定两个验证,如果两者都成功,则返回附加值的成功。如果两者都失败,则返回附加值的失败。否则,它返回成功的值。这需要成功类型的隐式Semigroup实例。

答案 1 :(得分:4)

我会做这样的事情:

scala> List(1.success[String], 2.success[String], "3".failure[Int], "4".failure[Int]).partition(_.isSuccess)
res2: (List[scalaz.Validation[java.lang.String,Int]], List[scalaz.Validation[java.lang.String,Int]]) = (List(Success(1), Success(2)),List(Failure(3), Failure(4)))

scala> val fun = (_:List[Validation[String, Int]]).reduceLeft(_ append _)
fun: List[scalaz.Validation[String,Int]] => scalaz.Validation[String,Int] = <function1>

scala> fun <-: res2 :-> fun
res3: (scalaz.Validation[String,Int], scalaz.Validation[String,Int]) = (Success(3),Failure(34))

UPD:合并#129#130后,您可以将fun更改为(_:List[Validation[String, Int]]).concatenate(_:List[Validation[String, Int]]).suml

bimap喜欢这样:

scala> List(1.success[String], 2.success[String], "3".failure[Int], "4".failure[Int]).partition(_.isSuccess).bimap(_.suml, _.suml)
res6: (scalaz.Validation[java.lang.String,Int], scalaz.Validation[java.lang.String,Int]) = (Success(3),Failure(34))

答案 2 :(得分:1)

您需要的是将Either[E, A]转换为Writer[List[E], A]Writer monad会记录您遇到的错误。

答案 3 :(得分:0)

听起来你想要一对(SomveValue, List[T]),其中T是你的'失败',虽然我称之为'警告'或'记录',因为你仍然得到一个结果,所以它不是真的故障。

不知道Scalaz是否对此有任何想法。