Eq 

LYAHFGG:

Eq は等値性をテストできる型に使われます。Eq のインスタンスが定義すべき関数は ==/= です。

Cats で Eq 型クラスと同じものも Eq と呼ばれている。 Eqnon/algebra から cats-kernel というサブプロジェクトに移行して、Cats の一部になった:

scala> import cats._, cats.data._, cats.implicits._
import cats._
import cats.data._
import cats.implicits._

scala> 1 === 1
res4: Boolean = true

scala> 1 === "foo"
<console>:40: error: type mismatch;
 found   : String("foo")
 required: Int
       1 === "foo"
             ^

scala> 1 == "foo"
<console>:40: warning: comparing values of types Int and String using `==' will always yield false
       1 == "foo"
         ^
res6: Boolean = false

scala> (Some(1): Option[Int]) =!= (Some(2): Option[Int])
res7: Boolean = true

標準の == のかわりに、Eq====!= 演算を可能とする。主な違いは IntString と比較すると === はコンパイルに失敗することだ。

algebra では neqveqv に基いて実装されている。

/**
 * A type class used to determine equality between 2 instances of the same
 * type. Any 2 instances `x` and `y` are equal if `eqv(x, y)` is `true`.
 * Moreover, `eqv` should form an equivalence relation.
 */
trait Eq[@sp A] extends Any with Serializable { self =>

  /**
   * Returns `true` if `x` and `y` are equivalent, `false` otherwise.
   */
  def eqv(x: A, y: A): Boolean

  /**
   * Returns `false` if `x` and `y` are equivalent, `true` otherwise.
   */
  def neqv(x: A, y: A): Boolean = !eqv(x, y)

  ....
}

これは多相性 (polymorphism) の例だ。型の A にとって等価性が何を意味しようと、 neqv はその逆だと定義されている。それが String でも Int でも変わらない。 別の言い方をすれば、Eq[A] が与えられたとき、=== は普遍的に =!= の逆だ。

気になるのが、Eq では等価 (equal) と同値 (equivalent) を同じように使っているフシがあることだ。 同値関係は例えば、「同じ誕生日を持つ」関係も含むのに対して、 等価性は代入原理を要請する。

Contents