簡體   English   中英

在Scala中編寫驗證函數

[英]Composing validating functions in Scala

假設我需要編寫一個驗證函數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
}

由於Validation是半群Validate也是半群並且(如果我將其定義為Kleisli )我可以按如下方式組成驗證函數:

val isEvenPositive = isEven |+| isPositive

假設我現在需要驗證X

case class X(x1: Int, // should be positive 
             x2: Int) // should be even

由於Validation是一個應用程序仿函數, Validate也是一個應用程序仿函數。

val x: Validate[X] = (isPositive |@| isEven)(X.apply) 

是否有意義 ?

當左手類型是半群時,您可以編寫驗證。 您的列表有效,但scalaz提供內置type ValidationNel[L, R] = Validation[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作為Validation簡寫)

(A => V[L, B], A => V[L, C]) => (A => V[L, (B, C)])

然后我不太確定正確的方法。 感覺應該有一兩個組合器可以做到這一點,但我還沒有找到它。

我已經設法編寫了這個組合,但我覺得可能有更好的方法。

  def composeV[A, B, C, L: Semigroup](f: A => Validation[L, B], g: A => Validation[L, C]): A => Validation[L, (B, C)] = {
    import scalaz.syntax.arrow._
    import scalaz.syntax.apply._
    import scalaz.std.function.function1Instance
    val oneInput: (A) => (Validation[L, B], Validation[L, C]) = f &&& g
    oneInput andThen {
      case (vb, vc) =>
        vb |@| vc apply { case x: (B, C) => x }
    }
  }

這是另一種方式:

def composeV[A, B, C, L: Semigroup](f: A => Validation[L, B], g: A => Validation[L, C]): A => Validation[L, (B, C)] = {
  import scalaz.syntax.apply._
  import scalaz.std.function.function1Instance
  f |@| g apply { case (vb, vc) =>
    vb |@| vc apply { case x: (B, C) => x }
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM