如何将序列函数应用于猫中的ValidatedNel列表?

时间:2019-01-11 14:20:11

标签: scala implicit scala-cats

我有以下代码

sealed trait DomainValidation {
  def errorMessage: String
}
type ValidationResult[A] = ValidatedNel[DomainValidation, A]
val ai:ValidationResult[String] = "big".validNel
val bi:ValidationResult[String] = "leboski".validNel
val l = List(ai,bi)

我想将l转换为ValidationResult[List[String]]。我遇到了sequence功能,但是我无法使用cats sequence,因为必须存在一些隐式的,它们知道如何处理ValidationResult[A]。但是我无法弄清楚到底需要什么。我写了以下

object helper {
  implicit class hello[A](l: List[ValidationResult[A]]) {
    def mysequence: ValidationResult[List[A]] = {
     val m = l.collect { case Invalid(a) => Invalid(a) }
     if (m.isEmpty) l.map { case Valid(a) => a }.validNel
     else /* merge the NonEmpty Lists */
    }
  }
}

我能够做l.mysequence。但是我该如何使用猫sequence

PS:我是scala初学者。很难学习:)。原谅任何不正确的提及。

1 个答案:

答案 0 :(得分:2)

以下内容应在Scala 2.12上按预期工作:

import cats.data.ValidatedNel, cats.syntax.validated._

// Your code:
sealed trait DomainValidation {
  def errorMessage: String
}
type ValidationResult[A] = ValidatedNel[DomainValidation, A]
val ai:ValidationResult[String] = "big".validNel
val bi:ValidationResult[String] = "leboski".validNel
val l = List(ai,bi)

然后:

scala> import cats.instances.list._, cats.syntax.traverse._
import cats.instances.list._
import cats.syntax.traverse._

scala> l.sequence
res0: ValidationResult[List[String]] = Valid(List(big, leboski))

您没有显示代码或解释什么不起作用,因此很难诊断出问题,但是很可能是以下问题之一:

  1. 您使用的是Scala 2.11,其中.sequence要求您在编译器选项中启用-Ypartial-unification。如果您使用的是sbt,则可以通过在scalacOptions += "-Ypartial-unification"上添加build.sbt来实现(假设您使用的是2.11.9 +)。
  2. 您已经省略了必要的导入之一。您至少需要Traverse的{​​{1}}实例和List的语法。上面的示例代码包括您需要的两次导入,或者您可以只导入Traverse并简化您的生活。

如果这不是这两件事之一,您可能需要在问题中包含更多详细信息,以便我们提供帮助。