nikita-volkov / typeclasses / Typeclasses.Classes.Hashing

Hashing typeclass definition and its instances for basic types. Implements fast non-cryptographic hashing for arbitrary types, suitable for implementing generic hashing-based datastructures, like hash-tables and hash-sets.

Much inspired by the "hashable" Haskell library.

Definition


type alias Hashing a =
{ hash : a -> Basics.Int
, hashWithSalt : Basics.Int -> a -> Basics.Int 
}

Explicit typeclass which implements hashing for type a.

Construction utilities

hash : (a -> Basics.Int) -> Hashing a

Construct from just the hashing function.

hashWithSalt : (Basics.Int -> a -> Basics.Int) -> Hashing a

Construct from just the hashing function, which combines the hash with salt.

Instance transformation utilities

map : (b -> a) -> Hashing a -> Hashing b

Map over the owner type of an instance to produce a new instance.

Please notice that mapping is contravariant (i.e., (b -> a) instead of (a -> b)).

concat : List (Hashing a) -> Hashing a

Compose multiple instances together.

Allows to create instances for product-types (records). E.g.,

type alias Person = { name : String, age : Int }

hashing : Hashing Person
hashing =
  Hashing.concat
    [
      Hashing.map .name (Hashing.string 4),
      Hashing.map .age Hashing.int
    ]

Instances

bool : Hashing Basics.Bool

Instance for Bool.

int : Hashing Basics.Int

Instance for Int.

float : Hashing Basics.Float

Instance for Float.

char : Hashing Char

Instance for Char.

string : Basics.Int -> Hashing String

Hashing instance for strings, determined by sampling. Sampling determines the maximum amount of characters to be picked from the string while constructing the hash, allowing you to control the balance between the quality of hashing and its performance.

maybe : Hashing a -> Hashing (Maybe a)

Instance for Maybe, which utilizes an instance for its element.

either : Hashing a -> Hashing b -> Hashing (Either a b)

Instance for Either, which utilizes instances for its contents.

Allows to create instances for sum-types (ADTs with multiple constructors). E.g.,

type IntOrBoolOrString = Int Int | Bool Bool | String String

hashing : Hashing IntOrBoolOrString
hashing =
  either int (either bool (string 3)) |>
  map (\ a -> case a of
    Int b -> Left b
    Bool b -> Right (Left b)
    String b -> Right (Right b))

list : Hashing a -> Hashing (List a)

Instance for List, which utilizes an instance for its element. Traverses the list in whole.

array : Hashing a -> Basics.Int -> Hashing (Array a)

Hashing instance for arrays, determined by the Hashing instance for elements and sampling. Sampling determines the maximum amount of elements to be picked from the array while constructing the hash, allowing you to control the balance between the quality of hashing and its performance.