Scalaz:我如何累积失败或将函数应用于不同类型的验证?
发布时间:2020-12-16 09:27:41 所属栏目:安全 来源:网络整理
导读:我有19个字符串需要验证为各种类型.当所有验证成功时,我想实例化一个表示电子表格行的类(其中列不是全部具有相同的类型). 当一个或多个字符串无法验证时,我希望在NonEmptyList中累积错误. 如果有12个或更少的项目,我可以使用| @ |或申请12.如果我使用for表达
我有19个字符串需要验证为各种类型.当所有验证成功时,我想实例化一个表示电子表格行的类(其中列不是全部具有相同的类型).
当一个或多个字符串无法验证时,我希望在NonEmptyList中累积错误. 如果有12个或更少的项目,我可以使用| @ |或申请12.如果我使用for表达式,它会快速失败并且不会发生累积. 当for表达式失败时,我可以对失败进行排序,但这意味着我循环两次.有没有办法使用scalaz将每个验证成功拉入变量(如果我使用for表达式来实例化类),同时累积所有失败? 解决方法
假设我们有一个案例类(可能有超过12个成员):
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 – 你只需写: Foo <$> goodA <*> goodB <*> goodC <*> goodD 不幸的是,Scala的弱类型推断要求我们以错误的顺序编写参数. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |