繁体   English   中英

如何使用应用函子来结合Scalaz验证

[英]How to use applicative functors to combine Scalaz validations

无法确定是否可以使用Scalaz 7编写类似的内容。我试图用代码块内的注释来表达自己。

def validate1(p: String) = ValidationNel[String, Value] = ...
def validate2(p: String) = ValidationNel[String, Value] = ...

validateCombination(p1: String, p2: String) = {
  // I would like to write something like
  (validate1(p1) |@| validate2(p2)) { (v1, v1) =>
    // And validate the combinations here and return successNel of failNel
  }
}

def validate(p1: String, p2: String, p3: String) = {
  (validateCombination(p1, p2) |@| validate1(p3)) { (v1, v2, v3) =>
    // Notice the three parameters I want to have here
  }
}

我最终在validateCombinations中遇到了不同类型的令人困惑的编译错误,或者在validate函数中只有两个用于应用函子的参数,其中之一是ValidationNel [...]类型。

您可以在validateCombination方法中使用.flatMap(identity)来生成ValidationNel[String, (Value, Value)]并在方法validate pattern matching ,如下所示:

def validateCombination(p1: String, p2: String): ValidationNel[String, (Value, Value)] = {
  // I would like to write something like
  (validate1(p1) |@| validate2(p2)) { (v1, v1) =>
    (v1, v2).successNel[String]
  }.flatMap(identity)
}

def validate(p1: String, p2: String, p3: String) = {
  (validateCombination(p1, p2) |@| validate1(p3)) { case ((v1, v2), v3) =>
    // Notice the three parameters I want to have here
  }
}

flatMap(身份)

通常,您将对嵌套容器使用flatten方法从M[M[T]]获取M[T] M[M[T]] 它适用于FutureOptionTry ,collection等。

在这种情况下, type M[T] = ValidationNel[String, T]

我不知道为什么Validation没有flatten方法,但是您始终可以使用flatMap(identity)代替flatten

比赛

正如本·詹姆斯 Ben James) 指出的那样 ,关于Validation flatMap令人怀疑。 您可以始终使用match代替它:

(validate1(p1) |@| validate2(p2)) { (v1, v1) =>
  (v1, v2).successNel[String]
} match {
  case Success(s) => s
  case Failure(f) => Failure(f)
}

模式匹配

模式匹配是处理元组的常用方法。 例如,对于foldLeft方法,它很有用,例如foldLeft(1 -> 2){ case ((a, b), c) => ??? } foldLeft(1 -> 2){ case ((a, b), c) => ??? }

如果您发现自己在Tuple上使用getters _N ,则可能应该使用模式匹配。

理解

正如Daniel C. Sobral所 指出的那样 ,理解力可能更容易理解。

您可以在您的validate方法中使用它,如下所示:

def validate(p1: String, p2: String, p3: String) = {
  for{
    (v1, v2) <- validateCombination(p1, p2) // pattern matching
    v3 <- validate1(p3)
  } yield ??? // Your code here
}

它涉及没有case关键字的模式匹配。

请注意,对于comprehension,在validateCombination(p1, p2)上调用flatMap ,因此,如果validateCombination(p1, p2)Failure ,您将丢失来自validate1(p3)错误消息。 相反, |@| 从双方收集所有错误消息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM