将List [String]转换为函数中的ValidationNEL [String,A]

时间:2012-09-25 16:21:49

标签: scala types scalaz

我有一个带有以下签名的功能

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。是否有一种标准的方法来推导出我想要的结果?

1 个答案:

答案 0 :(得分:5)

由于errors可能是空List,并且您限制自己没有类型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!"))

为什么不将errors作为NonEmptyList传递 - 如果您在编译时遇到错误,可能只会使用此函数。

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))