加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

在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 }
  }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读