// Core types
interface HashMap<K, V> extends Iterable<[K, V]> {}
type UpdateFn<V> = (option: Option<V>) => Option<V>
// Creation
const empty: <K = never, V = never>() => HashMap<K, V>
const make: <Entries extends ReadonlyArray<readonly [any, any]>>(
...entries: Entries
) => HashMap<K, V>
const fromIterable: <K, V>(entries: Iterable<readonly [K, V]>) => HashMap<K, V>
// Query
const get: {
<K>(key: K): <V>(self: HashMap<K, V>) => Option<V>
<K, V>(self: HashMap<K, V>, key: K): Option<V>
}
const has: {
<K>(key: K): <V>(self: HashMap<K, V>) => boolean
<K, V>(self: HashMap<K, V>, key: K): boolean
}
const size: <K, V>(self: HashMap<K, V>) => number
const isEmpty: <K, V>(self: HashMap<K, V>) => boolean
// Transform
const set: {
<K, V>(key: K, value: V): (self: HashMap<K, V>) => HashMap<K, V>
<K, V>(self: HashMap<K, V>, key: K, value: V): HashMap<K, V>
}
const remove: {
<K>(key: K): <V>(self: HashMap<K, V>) => HashMap<K, V>
<K, V>(self: HashMap<K, V>, key: K): HashMap<K, V>
}
const modify: {
<K, V>(key: K, f: (v: V) => V): (self: HashMap<K, V>) => HashMap<K, V>
<K, V>(self: HashMap<K, V>, key: K, f: (v: V) => V): HashMap<K, V>
}
// Map
const map: {
<V, K, A>(f: (value: V, key: K) => A): (self: HashMap<K, V>) => HashMap<K, A>
<K, V, A>(self: HashMap<K, V>, f: (value: V, key: K) => A): HashMap<K, A>
}
// Fold
const reduce: {
<Z, V, K>(zero: Z, f: (acc: Z, value: V, key: K) => Z): (self: HashMap<K, V>) => Z
<K, V, Z>(self: HashMap<K, V>, zero: Z, f: (acc: Z, value: V, key: K) => Z): Z
}