簡體   English   中英

折疊在NonEmptyList上

[英]Fold on 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))

最后一次fold會導致編譯錯誤。

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, check2, check3))

NonEmptyList應該是折疊的候選者。 驗證組合也應該在那里。 至於我的類, ChechViolationNonEmptyList因此它不需要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))
      }
    }

如果你仔細聆聽他們的類型,請指導你;)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM