Hash.flix
/*
* Copyright 2020 Matthew Lutze, Esben Bjerre
*
* Use of this source code is governed by the Apache 2.0 license
* that can be found in the LICENSE.md file.
*/
///
/// Trait for types that can be hashed, and its functions.
///
pub mod Hash {
import java.lang.Byte
import java.lang.Character
import java.lang.Double
import java.lang.Float
import java.lang.Integer
import java.lang.Long
import java.lang.Short
///
/// Trait for types that can be hashed.
///
pub trait Hash[a] {
///
/// Returns a hash value for the given x.
///
pub def hash(x: a): Int32
}
instance Hash[Unit] {
pub def hash(_x: Unit): Int32 = 0
}
instance Hash[Bool] {
pub def hash(x: Bool): Int32 = match x {
case true => 1231
case false => 1237
}
}
instance Hash[Char] {
pub def hash(x: Char): Int32 = Character.hashCode(x)
}
instance Hash[Float32] {
pub def hash(x: Float32): Int32 = Float.hashCode(x)
}
instance Hash[Float64] {
pub def hash(x: Float64): Int32 = Double.hashCode(x)
}
instance Hash[BigDecimal] {
pub def hash(x: BigDecimal): Int32 = x.hashCode()
}
instance Hash[Int8] {
pub def hash(x: Int8): Int32 = Byte.hashCode(x)
}
instance Hash[Int16] {
pub def hash(x: Int16): Int32 = Short.hashCode(x)
}
instance Hash[Int32] {
pub def hash(x: Int32): Int32 = Integer.hashCode(x)
}
instance Hash[Int64] {
pub def hash(x: Int64): Int32 = Long.hashCode(x)
}
instance Hash[String] {
pub def hash(x: String): Int32 = x.hashCode()
}
instance Hash[BigInt] {
pub def hash(x: BigInt): Int32 = x.hashCode()
}
instance Hash[(a1, a2)] with Hash[a1], Hash[a2] {
pub def hash(t: (a1, a2)): Int32 = match t {
case (x1, x2) => Hash.hash(x1) `Hash.combine` Hash.hash(x2)
}
}
instance Hash[(a1, a2, a3)] with Hash[a1], Hash[a2], Hash[a3] {
pub def hash(t: (a1, a2, a3)): Int32 = match t {
case (x1, x2, x3) => Hash.hash(x1) `Hash.combine` Hash.hash(x2) `Hash.combine` Hash.hash(x3)
}
}
instance Hash[(a1, a2, a3, a4)] with Hash[a1], Hash[a2], Hash[a3], Hash[a4] {
pub def hash(t: (a1, a2, a3, a4)): Int32 = match t {
case (x1, x2, x3, x4) =>
Hash.hash(x1) `Hash.combine` Hash.hash(x2) `Hash.combine` Hash.hash(x3) `Hash.combine` Hash.hash(x4)
}
}
instance Hash[(a1, a2, a3, a4, a5)] with Hash[a1], Hash[a2], Hash[a3], Hash[a4], Hash[a5] {
pub def hash(t: (a1, a2, a3, a4, a5)): Int32 = match t {
case (x1, x2, x3, x4, x5) =>
Hash.hash(x1) `Hash.combine` Hash.hash(x2) `Hash.combine` Hash.hash(x3) `Hash.combine` Hash.hash(x4)
`Hash.combine` Hash.hash(x5)
}
}
instance Hash[(a1, a2, a3, a4, a5, a6)] with Hash[a1], Hash[a2], Hash[a3], Hash[a4], Hash[a5], Hash[a6] {
pub def hash(t: (a1, a2, a3, a4, a5, a6)): Int32 = match t {
case (x1, x2, x3, x4, x5, x6) =>
Hash.hash(x1) `Hash.combine` Hash.hash(x2) `Hash.combine` Hash.hash(x3) `Hash.combine` Hash.hash(x4)
`Hash.combine` Hash.hash(x5)
`Hash.combine` Hash.hash(x6)
}
}
instance Hash[(a1, a2, a3, a4, a5, a6, a7)] with Hash[a1], Hash[a2], Hash[a3], Hash[a4], Hash[a5], Hash[a6], Hash[a7] {
pub def hash(t: (a1, a2, a3, a4, a5, a6, a7)): Int32 = match t {
case (x1, x2, x3, x4, x5, x6, x7) =>
Hash.hash(x1) `Hash.combine` Hash.hash(x2) `Hash.combine` Hash.hash(x3) `Hash.combine` Hash.hash(x4)
`Hash.combine` Hash.hash(x5)
`Hash.combine` Hash.hash(x6)
`Hash.combine` Hash.hash(x7)
}
}
instance Hash[(a1, a2, a3, a4, a5, a6, a7, a8)] with Hash[a1], Hash[a2], Hash[a3], Hash[a4], Hash[a5], Hash[a6], Hash[a7], Hash[a8] {
pub def hash(t: (a1, a2, a3, a4, a5, a6, a7, a8)): Int32 = match t {
case (x1, x2, x3, x4, x5, x6, x7, x8) =>
Hash.hash(x1) `Hash.combine` Hash.hash(x2) `Hash.combine` Hash.hash(x3) `Hash.combine` Hash.hash(x4)
`Hash.combine` Hash.hash(x5)
`Hash.combine` Hash.hash(x6)
`Hash.combine` Hash.hash(x7)
`Hash.combine` Hash.hash(x8)
}
}
instance Hash[(a1, a2, a3, a4, a5, a6, a7, a8, a9)] with Hash[a1], Hash[a2], Hash[a3], Hash[a4], Hash[a5], Hash[a6], Hash[a7], Hash[a8], Hash[a9] {
pub def hash(t: (a1, a2, a3, a4, a5, a6, a7, a8, a9)): Int32 = match t {
case (x1, x2, x3, x4, x5, x6, x7, x8, x9) =>
Hash.hash(x1) `Hash.combine` Hash.hash(x2) `Hash.combine` Hash.hash(x3) `Hash.combine` Hash.hash(x4)
`Hash.combine` Hash.hash(x5)
`Hash.combine` Hash.hash(x6)
`Hash.combine` Hash.hash(x7)
`Hash.combine` Hash.hash(x8)
`Hash.combine` Hash.hash(x9)
}
}
instance Hash[(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)] with Hash[a1], Hash[a2], Hash[a3], Hash[a4], Hash[a5], Hash[a6], Hash[a7], Hash[a8], Hash[a9], Hash[a10] {
pub def hash(t: (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)): Int32 = match t {
case (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) =>
Hash.hash(x1) `Hash.combine` Hash.hash(x2) `Hash.combine` Hash.hash(x3) `Hash.combine` Hash.hash(x4)
`Hash.combine` Hash.hash(x5)
`Hash.combine` Hash.hash(x6)
`Hash.combine` Hash.hash(x7)
`Hash.combine` Hash.hash(x8)
`Hash.combine` Hash.hash(x9)
`Hash.combine` Hash.hash(x10)
}
}
///
/// Combines the two given hash values.
///
pub def combine(h1: Int32, h2: Int32): Int32 = {
h1 * magic() + h2
}
///
/// Returns a number used for combining hash values.
///
pub def magic(): Int32 = -1640531535
}