【问题标题】:Convert List[String] into ValidationNEL[String, A] in a function在函数中将 List[String] 转换为 ValidationNEL[String, A]
【发布时间】:2012-09-25 16:21:49
【问题描述】:

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

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。有没有一种标准方法可以得出我正在寻找的结果?

【问题讨论】:

    标签: scala types scalaz


    【解决方案1】:

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

    【讨论】:

    • 那是真的,我没有想到这一点(呃)。如果 errors 在运行时计算,那将很有用,但我认为他会在他的代码中写出文字。我怀疑“哎呀,你忘了在代码中写错误”在运行时会是一个有用的错误。
    • 在看到您的回答 Ben 之前,我已经对代码中的非空列表进行了更改 - 我同意这是最好的解决方案。
    • .toNel 方法在哪里定义?我找不到它:(
    猜你喜欢
    • 2019-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-01
    • 2021-09-17
    • 2021-01-13
    • 2021-12-21
    • 2018-06-11
    相关资源
    最近更新 更多