8

我有一个具有以下签名的函数

def reject[A](errors: List[String]): ValidationNEL[String, A]

由于这是一个拒绝方法,因此A永远不会返回该类型,但我需要将其反映以匹配签名。我正在使用 lambdas 类型来获得我想要的结果,如下所示:

errors.map(Failure[String, A](_).liftFailNel).sequence[({type l[a] = ValidationNEL[String, a]})#l, A]

这使用类型List[A](或看起来),而不是我想要的类型A。有没有一种标准的方法来得出我正在寻找的结果?

4

1 回答 1

5

因为errors可能是一个空的List,并且你限制自己没有 type 的值A,我认为你不能把它写成一个总函数。要编写此类型签名,您需要通过假装空列表案例不存在来作弊,例如

def reject[A](errors: List[String]): ValidationNEL[String, A] =
  Failure(errors.toNel.get) // bad!

编辑:正如 Apocalisp 指出的那样,您当然可以通过为空列表引入错误来使其成为一个整体功能。但我只会errors在运行时计算,我怀疑这不是你的用例,因为它会导致愚蠢的错误,例如:

def reject[A](errors: List[String]): ValidationNEL[String, A] =
  Failure(errors.toNel getOrElse NonEmptyList("Error: There were no errors!"))

为什么不通过errorsas aNonEmptyList来代替 - 如果您在编译时有错误要使用,大概您只使用此函数。

def reject[A](errors: NonEmptyList[String]): ValidationNEL[String, A] =
  Failure(errors)

NonEmptyList.apply您可以通过复制(并将其专门用于)的签名来使用此简洁器String

def reject[A](h: String, t: String*): ValidationNEL[String, A] =
  Failure(NonEmptyList(h, t: _*))

让我们试一试:

scala> reject("foo", "bar", "baz")
res0: scalaz.package.ValidationNEL[String,Nothing] = Failure(NonEmptyList(foo, bar, baz))
于 2012-09-25T16:53:41.713 回答