@algosail/pair
v0.1.0
Published
Small collection of FP utilities for working with pairs.
Readme
@algosail/pair
Ordered 2-tuple (pair) utilities. Pairs are plain two-element JavaScript arrays [a, b].
Contents
pair
pair :: a -> b -> [a, b]Constructs a 2-element tuple.
pair(1)(2) // => [1, 2]
pair('key')('val') // => ['key', 'val']
pair(true)(null) // => [true, null]dup
dup :: a -> [a, a]Duplicates a value into a pair.
dup(3) // => [3, 3]
dup('hi') // => ['hi', 'hi']
dup([1, 2]) // => [[1, 2], [1, 2]]fst / snd
fst :: [a, b] -> a
snd :: [a, b] -> bExtract the first or second element.
fst([1, 2]) // => 1
snd([1, 2]) // => 2
// Useful in pipelines
const pairs = [
[1, 'a'],
[2, 'b'],
[3, 'c'],
]
pairs.map(fst) // => [1, 2, 3]
pairs.map(snd) // => ['a', 'b', 'c']merge / mergeSecond
merge :: [(a -> b), a] -> b
mergeSecond :: [a, (a -> b)] -> bApply the function element of a pair to the value element.
merge([(x) => x + 1, 5]) // => 6
merge([(s) => s.toUpperCase(), 'hello']) // => 'HELLO'
mergeSecond([5, (x) => x + 1]) // => 6
mergeSecond(['hello', (s) => s.length]) // => 5swap
swap :: [a, b] -> [b, a]Swaps the two elements.
swap([1, 2]) // => [2, 1]
swap(['key', 'val']) // => ['val', 'key']map
map :: (a -> c) -> [a, b] -> [c, b]Maps over the first element, leaving the second unchanged.
map((x) => x + 1)([1, 'x']) // => [2, 'x']
map((s) => s.length)(['hi', 0]) // => [2, 0]mapSecond
mapSecond :: (b -> d) -> [a, b] -> [a, d]Maps over the second element, leaving the first unchanged.
mapSecond((x) => x * 2)([1, 5]) // => [1, 10]
mapSecond((s) => s.trim())(['k', ' v ']) // => ['k', 'v']bimap
bimap :: (a -> c) -> (b -> d) -> [a, b] -> [c, d]Maps both elements simultaneously.
bimap((x) => x + 1)((x) => x * 2)([1, 3]) // => [2, 6]
bimap(String)(Boolean)([42, 0]) // => ['42', false]fold
fold :: ((c, a, b) -> c) -> c -> [a, b] -> cReduces a pair with a ternary function f(initial, first, second).
fold((acc, a, b) => acc + a + b)(0)([3, 4]) // => 7
fold((_, a, b) => a * b)(0)([3, 4]) // => 12
fold((s, k, v) => `${s}${k}=${v}`)('')(['x', 42]) // => 'x=42'foldWith
foldWith :: (a -> b -> c) -> [a, b] -> cApplies a curried binary function to both elements.
foldWith((a) => (b) => a + b)([1, 2]) // => 3
foldWith((a) => (b) => [a, b])([1, 2]) // => [1, 2] (round-trip)
foldWith(pair)([1, 2]) // => [1, 2] (same)traverse
traverse :: (b -> f b) -> (f (a->b) -> f a -> f b) -> ((a->b) -> f a -> f b) -> (a -> f b) -> [a, c] -> f [b, c]Applicative traversal over the first element. The second element is preserved.
// Traverse with Maybe
traverse(just)((mf) => (ma) => ap(mf)(ma))((f) => (ma) => map(f)(ma))((x) =>
x > 0 ? just(x * 2) : nothing(),
)([3, 'tag']) // => just([6, 'tag'])
traverse(just)((mf) => (ma) => ap(mf)(ma))((f) => (ma) => map(f)(ma))((x) =>
x > 0 ? just(x * 2) : nothing(),
)([-1, 'tag']) // => nothing()