假設我們有一個案例類(其中可能有超過十二名成員):
case class Foo(a: Int, b: Char, c: Symbol, d: String)
而且,我們正在代表錯誤字符串和定義一個類型別名爲方便:
type ErrorOr[A] = ValidationNel[String, A]
我們也有一些驗證結果:
val goodA: ErrorOr[Int] = 1.success
val goodB: ErrorOr[Char] = 'a'.success
val goodC: ErrorOr[Symbol] = 'a.success
val goodD: ErrorOr[String] = "a".success
val badA: ErrorOr[Int] = "x".failNel
val badC: ErrorOr[Symbol] = "y".failNel
現在我們可以這樣寫:
val foo = (Foo.apply _).curried
val good: ErrorOr[Foo] = goodD <*> (goodC <*> (goodB <*> (goodA map foo)))
val bad: ErrorOr[Foo] = goodD <*> (badC <*> (goodB <*> (badA map foo)))
這給了我們什麼,我們想:
scala> println(good)
Success(Foo(1,a,'a,a))
scala> println(bad)
Failure(NonEmptyList(x, y))
在Haskell,這將是much prettier -you'd只是寫:
Foo <$> goodA <*> goodB <*> goodC <*> goodD
Scala的弱類型推斷要求我們寫不幸的是,這些論點的順序錯誤。
這有點笨拙,但你可以[直接使用'<*>'(或'ap')](http://stackoverflow.com/a/11502894/334519),這會積累錯誤,並且沒有它可以應用的次數的任意限制。 –
難道你不能只將'字符串列表'映射到'驗證',然後''由'isFailure'分區結果列表。 – cmbaxter