我想将案例类与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 = ???
}
答案 0 :(得分:3)
我知道它可能对您没有帮助,但equals
上的NonEmptyList
方法在Scalaz 7中按预期工作。(编辑:实际上这也是now fixed in Scalaz 6,所以如果你愿意从源代码构建或等待6.0.5,无论如何你都会好的。)
在Scalaz 6.0.4或更早版本中使用Equal
解决此问题的方法仍然很自然,但您必须确保为{{1}构建正确的Equal
实例}}:
CC[M, N]
我们要求implicit def ccEqual[M: Equal, N: Equal] =
Equal.equalBy[CC[M, N], (M, NonEmptyList[N])] {
case CC(s, nel) => (s, nel)
}
和M
都有N
个实例。然后,编译器可以为Equal
构建Equal
实例,然后为NonEmptyList[N]
构建(M, NonEmptyList[N])
实例。从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
}
使用一点类型魔法(例如通过Scalaz 7 typelevel
或更容易使用Shapeless),您可以让编译器为Equal
个实例生成Equal
个实例1}}成员的实例,但自己写出来并不难。