On this page:
Equatable
Equatable.hash
Equatable.identity_  hash
Equatable.hash_  code_  combine
Equatable.hash_  code_  combine_  unordered
8.16.0.2

9.1 Equatables🔗ℹ

Any value is equatable. Implementing the Equatable interface customizes the way that instances of a class are compared for == and hashed for maps and sets that use ==.

Provided only in the class space, not the annot space.

An interface that a class can implement (publicly or privately) to customize the way its objects are compared for == and hashed for maps and sets that use ==. The interface has two methods:

A class gets a default equality implementation that recurs to compare fields only if the class has no mutable fields, and that matches === when the class has mutable fields. Normally, Equatable should be implemented privately, so that the methods do not have to check what class other instantiates or whether recur is a function.

class Posn(x, y):

  private field cache = #false

  method dist():

    cache || (block:

                def v = math.sqrt(x*x + y*y)

                cache := v

                v)

  // since `cache` is mutable, the default equality

  // comparison would only make `===` objects equal

  private implements Equatable

  private override equals(other :: Posn, recur):

    recur(x, other.x) && recur(y, other.y)

  private override hash_code(recur):

    Equatable.hash_code_combine(recur(x), recur(y))

> Posn(3, 4) == Posn(3, 4)

#true

function

fun Equatable.hash(v :: Any) :: Int

Returns a hash code for v that is consistent with ==.

Returns a hash code for v that is consistent with ===.

function

fun Equatable.hash_code_combine(hc :: Int, ...)

  :: Int

 

function

fun Equatable.hash_code_combine_unordered(hc :: Int, ...)

  :: Int

Combines hash codes to produce a new one. Information is generally lost in the combination, but this combining function mixes integers in a suitable way to produce good results for hashing.

See Equatable for an example.