在Scala中编写验证函数
发布时间:2020-12-16 08:44:29 所属栏目:安全 来源:网络整理
导读:假设我需要编写一个验证函数Validate [A]: type Status[A] = Validation[List[String],A]type Validate[A] = A = Status[A] // should be Kleisli 如果输入有效,则该函数返回带有输入的Success;如果不是,则返回带有错误列表的Failure. 例如, val isPositive
假设我需要编写一个验证函数Validate [A]:
type Status[A] = Validation[List[String],A] type Validate[A] = A => Status[A] // should be Kleisli 如果输入有效,则该函数返回带有输入的Success;如果不是,则返回带有错误列表的Failure. 例如, val isPositive: Validate[Int] = {x: Int => if (x > 0) x.success else List(s"$x is not positive").failure } val isEven: Validate[Int] = {x: Int => if (x % 2 == 0) x.success else List(s"$x is not even").failure } 由于验证是半群验证也是半群并且(如果我将其定义为Kleisli)我可以按如下方式组成验证函数: val isEvenPositive = isEven |+| isPositive 假设我现在需要验证X: case class X(x1: Int,// should be positive x2: Int) // should be even 由于验证是一个应用程序仿函数,验证也是一个应用程序仿函数. val x: Validate[X] = (isPositive |@| isEven)(X.apply) 是否有意义 ? 解决方法
当左手类型是半群时,您可以编写验证.您的列表有效,但scalaz提供内置类型ValidationNel [L,R] =验证[NonEmptyList [L],R],您应该使用它.有一些便利功能,如aValidation.toValidationNel,用于提升单个错误的值.组合的验证将有一个左侧,所有失败累积或右手与成功应用于您的功能
def foo: ValidationNel[String,Int] def bar: ValidationNel[String,Double] val composed: ValidationNel[String,Double] = foo(input) |@| bar(input) apply { (i: Int,d: Double) => i * d } 如果你正在寻找一个新的单一函数的组合形式(V作为验证的简写) (A => V[L,B],A => V[L,C]) => (A => V[L,(B,C)]) 然后我不太确定正确的方法.感觉应该有一两个组合器可以做到这一点,但我还没有找到它. 我已经设法编写了这个组合,但我觉得可能有更好的方法. def composeV[A,B,C,L: Semigroup](f: A => Validation[L,g: A => Validation[L,C]): A => Validation[L,C)] = { import scalaz.syntax.arrow._ import scalaz.syntax.apply._ import scalaz.std.function.function1Instance val oneInput: (A) => (Validation[L,Validation[L,C]) = f &&& g oneInput andThen { case (vb,vc) => vb |@| vc apply { case x: (B,C) => x } } } 这是另一种方式: def composeV[A,C)] = { import scalaz.syntax.apply._ import scalaz.std.function.function1Instance f |@| g apply { case (vb,vc) => vb |@| vc apply { case x: (B,C) => x } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |