我正在尝试使用猫库,但我很难在导入和创建的东西之间导航.我的问题如下:
sealed trait Checks
case class CheckViolation(id: Long, msg: String) extends Checks
case class ChecksPassed(ids: Seq[Long]) extends Checks
Run Code Online (Sandbox Code Playgroud)
这是我想要使用的数据结构.每个违规都应该作为具有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))
Run Code Online (Sandbox Code Playgroud)
最后一个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))
Run Code Online (Sandbox Code Playgroud)
NonEmptyList应该是一个折叠的候选人.验证组合也应该在那里.至于我的课,ChechViolation是NonEmptyList因此它不需要幺实例.因为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._
Run Code Online (Sandbox Code Playgroud)
好的,我明白了.
所以我留下一个答案,也许有人会发现它有用.
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))
}
}
Run Code Online (Sandbox Code Playgroud)
如果你仔细聆听他们的类型,请指导你;)
| 归档时间: |
|
| 查看次数: |
708 次 |
| 最近记录: |