2

NonEmptyListcase クラスと scalazフィールドを比較したい。==orは機能しません。これは、比較されたオブジェクトが呼び出し元と同じインスタンスであるかどうかをチェックするメソッド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 = ???
}
4

1 に答える 1

3

おそらく役に立たないことはわかっていますが、Scalaz 7 でのメソッドは期待どおりに機能equalsます。 5 とにかく元気です。)NonEmptyList

Equalただし、Scalaz 6.0.4 以前でもこの問題を解決する自然な方法はまだあります — の正しい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やShapelesstypelevelを使うとより簡単に) を使えば、コンパイラに任意のケース クラスのインスタンスをそのメンバーのインスタンスとともに生成させることができますが、それらを自分で書き出すのはそれほど難しくありません。EqualEqual

于 2012-11-18T14:30:59.203 に答える