繁体   English   中英

以 scalaz.NonEmptyList[A] 作为成员和 ===、equals、== 的 case 类

[英]case class with scalaz.NonEmptyList[A] as member and the ===, equals, ==

我想将 case 类与 scalaz NonEmptyList字段进行比较。 ==euqls不起作用,我知道这是因为NonEmptyList.equals方法检查比较对象是否与调用者相同的实例。 另一方面,scalaz ===函数适用于NonEmptyList前提是范围内必须有隐式Equals

问题是我想让我的案例类通用,并希望它的实例易于比较。

这该怎么做?

如果唯一的解决方案是提供自定义def equals(obj: Any): Boolean方法,请在下面发布。

我的代码:

object Problem {

  case class CC[M, N](s: M, nel: NonEmptyList[N])

  CC(1, 2.wrapNel) == CC(1, 2.wrapNel) //false

  CC(1, 2.wrapNel) equals CC(1, 2.wrapNel) //false


  implicit def cCEquals[M, N] = equalA[CC[M, N]]

  CC(1, 2.wrapNel) === CC(1, 2.wrapNel) //false

  //override def equals(obj: Any): Boolean = ???
}

我知道它可能对您没有帮助,但是NonEmptyList上的equals方法在 Scalaz 7 中按预期工作。(编辑:实际上这现在在 Scalaz 6中也已修复,因此如果您愿意从源代码构建或等待6.0.5,反正你会没事的。)

不过,在 Scalaz 6.0.4 或更早版本中使用Equal仍然有一种自然的方法可以解决这个问题——您只需要确保为CC[M, N]构建正确的Equal实例:

implicit def ccEqual[M: Equal, N: Equal] =
  Equal.equalBy[CC[M, N], (M, NonEmptyList[N])] {
    case CC(s, nel) => (s, nel)
  }

这里我们要求MN都有Equal实例。 然后编译器可以为NonEmptyList[N](M, NonEmptyList[N])构建一个Equal实例。 并且有一个从CC[M, N](M, NonEmptyList[N])的明显映射,我们可以使用Equal.equalBy将其转换为所需的实例。

如果您愿意对MN使用普遍平等,您可以这样做:

implicit def ccEqual[M, N] = new Equal[CC[M, N]] {
  def equal(a: CC[M, N], b: CC[M, N]) =
    a.s == b.s && Equal.NonEmptyListEqual(Equal.equalA[N]).equal(a.nel, b.nel)
}

或者甚至只是:

implicit def ccEqual[M, N] = new Equal[CC[M, N]] {
  def equal(a: CC[M, N], b: CC[M, N]) = a.s == b.s && a.nel.list == b.nel.list
}

随着一点点的typelevel魔术(例如,通过Scalaz 7的typelevel或更方便地与无形的),你可以让编译器产生Equal与任何情况下,类实例Equal为它的成员的情况下,但它不是太难把它们写出来自己。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM