在ScalaZ中,将Option[Validation[E, A]]转换为Validation[E, Option[A]]的惯用方式是什么?

例如,在以下假设代码中:

def convert(x: Option[Validation[E, A]]): Validation[E, Option[A]] =
  /* ??? */

def validateThing(thing: A): Validation[E, A] =
  /* whatever */

def exampleUseCase(maybeThing: Option[Thing]): Validation[E, Option[Thing]] = {
  val validated: Option[Validation[E, Thing]] = a.map(validateThing(_))

   // ...

  val result: Validation[E, Option[Thing]] = convert(validated)
  result
}

在惯用的ScalaZ中convert的实现是什么样的?

最佳答案

我可以在这里看到两种可能的解决方案。可能是最简单的一种在参数上使用模式匹配的示例,例如:

def convert[A](v: Option[Validation[Throwable, A]]): Validation[Throwable, Option[A]] = {
  v match {
    case None => Validation.success(None)
    case Some(valid) => valid.map(Some(_))
  }
}

对于基于Scalaz的解决方案,我在考虑sequence,这样您就需要使用ValidationNel而不是Validation来聚合可能的问题,您可以使用convert来实现Traversable:
def convert[A](v: Option[ValidationNel[Throwable, A]]): ValidationNel[Throwable, Option[A]] =
  Traverse[Option].sequenceU(v)

请注意,实际上我使用的是sequenceU而不是sequence,它只不过是内部Scalaz魔术用于正确的类型推断,因为Validation有两个类型参数。希望能帮助到你

关于scala - 将选项[Validation [E,A]]转换为验证[E,Option [A]],我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35443461/

10-12 22:58