scalaz 7.2.6 flatMap不是验证方法吗?

时间:2016-09-13 08:25:12

标签: scalaz

这适用于scalaz 7.0.6,但不适用于最新版本的scalaz,7.2.6。

import scalaz._, Scalaz._

def allDigits(s: String): Validation[String, String] =
  if (s.forall(_.isDigit)) s.success else "Not all digits".failure

def maxSizeOfTen(s: String): Validation[String, String] =
  if (s.length <= 10) s.success else "Too big".failure

def toInt(s: String) = try s.toInt.success catch {
  case _: NumberFormatException => "Still not an integer".failure
}

val validated1 = for {
  x <- allDigits("4234")
  y <- maxSizeOfTen(x)
  z <- toInt(y)
} yield z

我在scalaz 7.2.6上得到了这些错误:

value flatMap is not a member of scalaz.Validation[String,String]
      x <- allDigits("4234")
value flatMap is not a member of scalaz.Validation[String,String]
      y <- maxSizeOfTen(x)
...

如何使其在最新版本的scalaz上运行?

更新:根据接受的答案解决方案:

import scalaz._, Scalaz._

def allDigits(s: String): \/[String, String] =
  if (s.forall(_.isDigit)) s.right else "Not all digits".left

def maxSizeOfTen(s: String): \/[String, String] =
  if (s.length <= 10) s.right else "Too big".left

def toInt(s: String) = try s.toInt.right catch {
  case _: NumberFormatException => "Still not an integer".left
}

val validated1 = for {
  x <- allDigits("4234")
  y <- maxSizeOfTen(x)
  z <- toInt(y)
} yield z

2 个答案:

答案 0 :(得分:5)

验证不应与flatMap一起使用,因为它旨在累积失败,因此具有Applicative实例用于独立(无上下文)计算。 \/应该在您的情况下使用(依赖(或上下文敏感)计算)。 仍然,通过添加此导入,您可以实现您想要的: import Validation.FlatMap._

答案 1 :(得分:1)

正如先前的答案所指出的,当您要并行运行事物并立即获取所有错误时,验证很有用。

适用方法:

def allDigits(s: String): Validation[String, String] =
  if (s.forall(_.isDigit)) s.success else s"|error: '$s' Not all digits ".failure

def maxSizeOfTen(s: String): Validation[String, String] =
  if (s.length <= 10) s.success else s"|error: '$s' Too big".failure

def toInt(s: String) = try s.toInt.success catch {
  case _: NumberFormatException => "|Still not an integer".failure
}

val input = "4234"
val validated1 = (allDigits(input) |@| maxSizeOfTen(input)) { (x, _) => toInt(x) }
println(validated1)

val input2 = "123456789ten"
val validated2 = (allDigits(input2) |@| maxSizeOfTen(input2)) { (x, _) => toInt(x) }
println(validated2)

您将获得下一个输出:

Success(Success(4234))
Failure(|error: '123456789ten' Not all digits |error: '123456789ten' Too big)