Mad*_*Dog 8 types scala scalaz
我有一个具有以下签名的功能
def reject[A](errors: List[String]): ValidationNEL[String, A]
Run Code Online (Sandbox Code Playgroud)
由于这是拒绝方法,因此A永远不会返回类型,但我需要反映它以匹配签名.我正在弄乱类型lambdas以获得我想要的结果,如下所示:
errors.map(Failure[String, A](_).liftFailNel).sequence[({type l[a] = ValidationNEL[String, a]})#l, A]
Run Code Online (Sandbox Code Playgroud)
这使用类型List[A](或似乎),而不是我想要的类型A.有没有一种标准的方法来推导出我想要的结果?
因为errors可能是空的List,并且你限制自己没有类型的值A,我认为你不能把它写成一个总函数.要编写此类型签名,您需要通过假装空列表案例来作弊,例如
def reject[A](errors: List[String]): ValidationNEL[String, A] =
Failure(errors.toNel.get) // bad!
Run Code Online (Sandbox Code Playgroud)
编辑:正如Apocalisp指出的那样,你可以通过为空列表引入一个错误来使它成为一个完整的函数.但我只会errors在运行时计算,我怀疑这不是你的用例,因为它会导致愚蠢的错误,例如:
def reject[A](errors: List[String]): ValidationNEL[String, A] =
Failure(errors.toNel getOrElse NonEmptyList("Error: There were no errors!"))
Run Code Online (Sandbox Code Playgroud)
为什么不把它errors作为一个NonEmptyList代替 - 如果你在编译时有错误,大概只使用这个函数.
def reject[A](errors: NonEmptyList[String]): ValidationNEL[String, A] =
Failure(errors)
Run Code Online (Sandbox Code Playgroud)
您可以通过复制签名NonEmptyList.apply(并将其专门化String)来使用这个terser :
def reject[A](h: String, t: String*): ValidationNEL[String, A] =
Failure(NonEmptyList(h, t: _*))
Run Code Online (Sandbox Code Playgroud)
我们来试试吧:
scala> reject("foo", "bar", "baz")
res0: scalaz.package.ValidationNEL[String,Nothing] = Failure(NonEmptyList(foo, bar, baz))
Run Code Online (Sandbox Code Playgroud)