@algosail/strmap
v0.1.0
Published
Small collection of FP utilities for working with plain objects as maps.
Downloads
39
Readme
@algosail/strmap
Plain JS objects used as string-keyed maps (StrMap). Keys are always iterated in sorted order. Value comparisons take an explicit comparator.
Contents
- equals
- lte
- concat
- empty / zero
- size
- value
- singleton
- filter / reject
- map
- ap
- alt
- all / any / none
- elem
- reduce
- traverse
equals
equals :: ((v, v) -> Boolean) -> StrMap v -> StrMap v -> BooleanElement-wise equality over sorted keys.
equals((a, b) => a === b)({ a: 1, b: 2 })({ b: 2, a: 1 }) // => true (key order doesn't matter)
equals((a, b) => a === b)({ a: 1 })({ a: 2 }) // => false
equals((a, b) => a === b)({ a: 1 })({ a: 1, b: 2 }) // => falselte
lte :: ((v, v) -> Boolean) -> StrMap v -> StrMap v -> BooleanLexicographic ordering over sorted keys; values are compared on key ties.
lte((a, b) => a <= b)({ a: 1 })({ a: 2 }) // => true
lte((a, b) => a <= b)({ a: 2 })({ a: 1 }) // => false
lte((a, b) => a <= b)({ a: 1 })({ a: 1, b: 1 }) // => true (prefix)concat
concat :: StrMap v -> StrMap v -> StrMap vRight-biased merge — keys in b overwrite keys in a.
concat({ a: 1, b: 2 })({ b: 99, c: 3 }) // => { a: 1, b: 99, c: 3 }
concat({ a: 1 })({}) // => { a: 1 }empty / zero
empty :: () -> StrMap v
zero :: () -> StrMap vBoth return a new empty object. zero is the monoid identity.
empty() // => {}
zero() // => {}size
size :: StrMap v -> IntegerReturns the number of own enumerable keys.
size({ a: 1, b: 2, c: 3 }) // => 3
size({}) // => 0value
value :: String -> StrMap a -> Maybe aReturns Just(m[k]) if k is an own enumerable property; Nothing otherwise.
value('a')({ a: 1 }) // => just(1)
value('missing')({ a: 1 }) // => nothing()
value('toString')({ a: 1 }) // => nothing() — prototype keys excludedsingleton
singleton :: String -> a -> StrMap aCreates a single-entry map.
singleton('key')(42) // => { key: 42 }
singleton('x')([1, 2]) // => { x: [1, 2] }filter / reject
filter :: (v -> Boolean) -> StrMap v -> StrMap v
reject :: (v -> Boolean) -> StrMap v -> StrMap vKeep or remove entries by value predicate.
filter((v) => v > 1)({ a: 1, b: 2, c: 3 }) // => { b: 2, c: 3 }
reject((v) => v > 1)({ a: 1, b: 2, c: 3 }) // => { a: 1 }map
map :: (a -> b) -> StrMap a -> StrMap bApplies f to every value.
map((v) => v * 2)({ a: 1, b: 2, c: 3 }) // => { a: 2, b: 4, c: 6 }
map(String)({ x: 1, y: 2 }) // => { x: '1', y: '2' }ap
ap :: StrMap (a -> b) -> StrMap a -> StrMap bApplies functions to matching keys; only shared keys appear in the result.
ap({ a: (x) => x + 1, b: (x) => x * 2 })({ a: 10, b: 5, c: 99 })
// => { a: 11, b: 10 } — 'c' has no functionalt
alt :: StrMap v -> StrMap v -> StrMap vLeft-biased merge — keys from a overwrite keys from b.
alt({ a: 1 })({ a: 99, b: 2 }) // => { a: 1, b: 2 }all / any / none
all :: (v -> Boolean) -> StrMap v -> Boolean
any :: (v -> Boolean) -> StrMap v -> Boolean
none :: (v -> Boolean) -> StrMap v -> Booleanall((v) => v > 0)({ a: 1, b: 2 }) // => true
all((v) => v > 1)({ a: 1, b: 2 }) // => false
any((v) => v > 1)({ a: 1, b: 2 }) // => true
any((v) => v > 5)({ a: 1, b: 2 }) // => false
none((v) => v > 5)({ a: 1, b: 2 }) // => true
none((v) => v > 1)({ a: 1, b: 2 }) // => falseelem
elem :: ((v, v) -> Boolean) -> v -> StrMap v -> BooleanTrue when x is found among the values using the comparator.
elem((a, b) => a === b)(2)({ a: 1, b: 2, c: 3 }) // => true
elem((a, b) => a === b)(9)({ a: 1, b: 2, c: 3 }) // => falsereduce
reduce :: ((b, v) -> b) -> b -> StrMap v -> bLeft fold over values in sorted key order.
reduce((acc, v) => acc + v)(0)({ b: 2, a: 1, c: 3 }) // => 6 (visits a, b, c)
reduce((acc, v) => [...acc, v])([])({ b: 2, a: 1 }) // => [1, 2] (sorted)traverse
traverse :: (b -> f b) -> (f (a->b) -> f a -> f b) -> ((a->b) -> f a -> f b) -> (v -> f b) -> StrMap v -> f (StrMap b)Applicative traversal — passes explicit apOf, apAp, apMap to work with any applicative.
// Traverse with Maybe — short-circuits on Nothing
const safeDouble = (v) => (v < 0 ? nothing() : just(v * 2))
traverse(just)((mf) => (ma) => ap(mf)(ma))((f) => (ma) => map(f)(ma))(
safeDouble,
)({ a: 1, b: 2 }) // => just({ a: 2, b: 4 })
traverse(just)((mf) => (ma) => ap(mf)(ma))((f) => (ma) => map(f)(ma))(
safeDouble,
)({ a: 1, b: -1 }) // => nothing()