微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

scala – 折叠在NonEmptyList上

我正在尝试使用猫库,但我很难在导入和创建的东西之间导航.我的问题如下:

sealed trait Checks
case class CheckViolation(id: Long,msg: String) extends Checks
case class ChecksPassed(ids: Seq[Long]) extends Checks

这是我想要使用的数据结构.每个违规都应该作为具有msg的对象保存,传递的检查可以聚合为仅保存id.

object BusinessRuleSetValidation extends App {

  type BRValidationResult = Validated[NonEmptyList[CheckViolation],ChecksPassed]

  def run(): BRValidationResult = {

    implicit val monoidChecksPassed = new Monoid[ChecksPassed] {
      override def empty: ChecksPassed = ChecksPassed(Seq())

      override def combine(x: ChecksPassed,y: ChecksPassed): ChecksPassed = ChecksPassed(x.ids ++ y.ids)
    }



    val check1: BRValidationResult = valid(ChecksPassed(2L))
    val check2: BRValidationResult = invalidNel(CheckViolation(1,"This check was violated"))
    val check3: BRValidationResult = invalidNel(CheckViolation(2,"This is a violation"))


    val p = Foldable[NonEmptyList].fold(NonEmptyList(check1,check2,check3))

最后一次折叠会导致编译错误.

BusinessRuleSetValidation.scala:48: Could not find implicit value for parameter A: cats.Monoid[cats.data.Validated[cats.data.OneAnd[com.adform.br.server.model.validation.CheckViolation,[+A]List[A]],com.adform.br.server.model.validation.ChecksPassed]]
[error]     val p = Foldable[NonEmptyList].fold(NonEmptyList(check1,check3))

NonEmptyList应该是折叠的候选者.验证组合也应该在那里.至于我的类,ChechViolation在NonEmptyList中,因此它不需要monoid实例.对于ChecksPassed,我创建了一个monoid实例,所以我真的没有得到这里缺少的东西.

编辑

我没有包含我的进口,它们在这里很重要:

import cats._
import cats.data.Validated._
import cats.data.{NonEmptyList,Validated,Xor}
import cats.data.OneAnd.oneAndFoldable
import cats.std.all._
import cats.Syntax.apply._
import cats.Syntax.order._
import cats.Syntax.xor._
import cats.Syntax.semigroup._

解决方法

好的,我明白了.

所以我留下一个答案,也许有人会发现它有用.

NonEmptyList不可能有Monoid.为什么? Monoid需要一个中性元素,对于列表来说是空的,但是我们的列表不允许这样做.

所以我改变了将检查从NEL分组到List的方式.

事实证明,我还需要创建一个Monoid for Validation,它看起来像这样:

implicit val brValidationResutlMonoid = new Monoid[BRValidationResult] {
      override def empty: BRValidationResult = valid(ChecksPassed(Seq.empty))

      override def combine(x: BRValidationResult,y: BRValidationResult): BRValidationResult = (x,y) match {
        case (Valid(a),Valid(b)) => valid(ChecksPassed(a.ids ++ b.ids))
        case (Valid(_),k @ Invalid(_)) => k
        case (f @ Invalid(_),Valid(_)) => f
        case (Invalid(l1),Invalid(l2)) => Invalid(l1.combine(l2))
      }
    }

如果你仔细聆听他们的类型,请指导你;)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐