![](/img/trans.png)
[英]Why does scalaz.NonEmptyList not support common list operations like “find”
[英]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)
}
这里我们要求M
和N
都有Equal
实例。 然后编译器可以为NonEmptyList[N]
和(M, NonEmptyList[N])
构建一个Equal
实例。 并且有一个从CC[M, N]
到(M, NonEmptyList[N])
的明显映射,我们可以使用Equal.equalBy
将其转换为所需的实例。
如果您愿意对M
和N
使用普遍平等,您可以这样做:
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.