Arr — array utilities
JavaScript arrays come with a full set of built-in methods, but they have two friction points in
pipelines: they put the data first (making partial application awkward), and they return undefined
when something isn’t found. Arr is a collection of array utilities that address both: data-last
functions that slot directly into pipe, and Maybe wherever something might be absent.
Safe access
Section titled “Safe access”JavaScript’s built-in access functions silently return undefined when an element doesn’t exist.
Arr makes the absence explicit:
These compose naturally with Maybe operations:
Search
Section titled “Search”findFirst, findLast, and findIndex all return Maybe for the same reason — the element might
not exist:
Transforming
Section titled “Transforming”The core transforms work exactly like their built-in counterparts, but curried for pipe:
partition splits into two groups — those that pass the predicate and those that don’t:
groupBy groups elements by a key function, returning a record where each group is a
NonEmptyList:
uniq removes duplicates using strict equality; uniqBy removes duplicates by a key
function:
sortBy sorts without mutating:
flatMap and flatten for working with nested arrays:
Slicing
Section titled “Slicing”Modifying by index
Section titled “Modifying by index”insertAt returns a new array with an item inserted before the element at a given index.
Negative indices are clamped to 0; indices beyond the array length append to the end:
removeAt returns a new array with the element at the given index removed. If the index is
out of bounds the original array is returned unchanged:
Combining arrays
Section titled “Combining arrays”zip pairs elements from two arrays, stopping at the shorter one:
zipWith combines elements with a function:
intersperse inserts a separator between every element:
chunksOf splits into fixed-size chunks:
reduce folds from the left:
Predicates
Section titled “Predicates”Traversing across types
Section titled “Traversing across types”The traverse family maps each element to a typed container and collects the results. For most
cases, traverseResult is what you want — it stops at the first failure and tells you what went
wrong. Use traverse when working with Maybe; use traverseTask when the operations are
independent and can run in parallel.
traverse — maps to Maybe, returns None if any element fails:
traverseResult — maps to Result, returns the first Err if any element fails:
traverseTask — maps to Task and runs all in parallel. Note: if you need sequential
processing that stops at the first error, use traverseTaskResult instead:
traverseTaskResult — maps to TaskResult and runs sequentially, short-circuiting on the
first Err:
sequence, sequenceResult, sequenceTask, sequenceTaskResult — shorthand for
when you already have an array of containers and want to flip Array<Maybe<A>> into
Maybe<Array<A>>:
When to use Arr
Section titled “When to use Arr”Use Arr when:
- You’re composing array operations inside a
pipechain and want to avoid data-first method calls - You need
Maybe-returning access functions (head,last,findFirst) instead ofundefined - You’re mapping or filtering and want the step to read as a named operation rather than an inline arrow function
- You need to traverse an array with a fallible or async operation and collect the results
Keep using the native array methods when:
- The operation is a one-liner in a function body where
.map()or.filter()is already clear - You don’t need the result to compose in a pipeline