All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cats.kernel.Hash.scala Maven / Gradle / Ivy

The newest version!
package cats.kernel

import scala.{specialized => sp}
import scala.util.hashing.Hashing

/**
 * A type class used to represent a hashing scheme for objects of a given type.
 * For any two instances `x` and `y` that are considered equivalent under the
 * equivalence relation defined by this object, `hash(x)` should equal `hash(y)`.
 * @author Tongfei Chen
 */
trait Hash[@sp A] extends Any with Eq[A] with Serializable { self =>

  /**
   * Returns the hash code of the given object under this hashing scheme.
   */
  def hash(x: A): Int

  // `Hash#toHashing` deliberately not implemented since `scala.util.hashing.Hashing` is only
  // compatible with universal equality.
}

abstract class HashFunctions[H[T] <: Hash[T]] extends EqFunctions[H] {

  def hash[@sp A](x: A)(implicit ev: H[A]): Int = ev.hash(x)

}

object Hash extends HashFunctions[Hash] {

  /** Fetch a `Hash` instance given the specific type. */
  @inline final def apply[A](implicit ev: Hash[A]): Hash[A] = ev

  def by[@sp A, @sp B](f: A => B)(implicit ev: Hash[B]): Hash[A] =
    new Hash[A] {
      def hash(x: A) = ev.hash(f(x))
      def eqv(x: A, y: A) = ev.eqv(f(x), f(y))
    }

  def fromHashing[A](implicit ev: Hashing[A]): Hash[A] =
    new Hash[A] {
      def hash(x: A) = ev.hash(x)
      def eqv(x: A, y: A) = x == y // universal equality
    }

  /**
   * Constructs a `Hash` instance by using the universal `hashCode` function and the universal equality relation.
   */
  def fromUniversalHashCode[A]: Hash[A] =
    new Hash[A] {
      def hash(x: A) = x.hashCode()
      def eqv(x: A, y: A) = x == y
    }

}

trait HashToHashingConversion {
  implicit def catsKernelHashToHashing[A](implicit ev: Hash[A]): Hashing[A] = new Hashing[A] {
    override def hash(x: A): Int = ev.hash(x)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy