Funx.List (funx v0.8.2)
View SourceThe Funx.List module provides utility functions for working with lists while respecting Eq and Ord instances. This allows for set-like operations, uniqueness constraints, and sorted collections that align with functional programming principles.
Features
- Equality-based Operations: Use
Eqinstances to compare elements for uniqueness, intersection, and difference. - Ordering Functions: Leverage
Ordinstances to sort and enforce uniqueness in sorted collections. - Set Operations: Perform union, intersection, difference, and symmetric difference while preserving custom equality logic.
- Subset & Superset Checks: Verify relationships between lists in terms of inclusion.
- Functional Constructs: Implements
MonadandFoldableprotocols for lists, supporting mapping, binding, and folding.
Usage Overview
- Deduplicate: Use
uniq/1to remove duplicates based onEq. - Combine: Use
union/2to merge lists without duplicates. - Filter: Use
intersection/2ordifference/2for set operations. - Sort: Use
sort/2orstrict_sort/2withOrdinstances. - Check Membership: Use
subset?/2orsuperset?/2to verify inclusion relationships. - Find Extremes: Use
min/2,max/2for safe min/max, ormin!/2,max!/2to raise on empty. - Group: Use
group/1to group consecutive equal elements.
Equality-Based Operations
uniq/1: Removes duplicates usingEq.union/2: Merges lists while preserving uniqueness.intersection/2: Returns elements common to both lists.difference/2: Returns elements from the first list not in the second.symmetric_difference/2: Returns elements unique to each list.group/1: Groups consecutive equal elements into sublists.partition/2: Partitions into elements equal to a value and those not.
Ordering Functions
sort/2: Sorts a list usingOrd.strict_sort/2: Sorts while ensuring uniqueness.group_sort/2: Sorts and groups consecutive equal elements.
Set Operations
subset?/2: Checks if one list is a subset of another.superset?/2: Checks if one list is a superset of another.
Min/Max Operations
min/2: Returns the minimum element wrapped inMaybe.min!/2: Returns the minimum element, raises on empty list.max/2: Returns the maximum element wrapped inMaybe.max!/2: Returns the maximum element, raises on empty list.
Monad Implementation
map/2: Transforms list elements.bind/2: Applies a function returning lists and flattens the result.ap/2: Applies functions in a list to elements in another list.
Foldable Implementation
fold_l/3: Performs left-associative folding.fold_r/3: Performs right-associative folding.
Summary
Functions
Concatenates a list of lists from left to right.
Returns the difference of two lists.
Returns true if the given value is an element of the list under the provided Eq.
Groups consecutive equal elements into sublists.
Sorts a list and then groups consecutive equal elements.
Returns the head of a list wrapped in Maybe.Just, or Maybe.Nothing if empty.
Returns the head of a list.
Returns the intersection of two lists.
Returns the maximum element in a list according to the given ordering.
Returns the maximum element in a list according to the given ordering.
Returns the minimum element in a list according to the given ordering.
Returns the minimum element in a list according to the given ordering.
Partitions a list into elements equal to a value and elements not equal.
Sorts a list using the given ordering module.
Sorts a list while ensuring uniqueness.
Checks if the first list is a subset of the second.
Checks if the first list is a superset of the second.
Returns the symmetric difference of two lists.
Returns the tail of a list.
Returns the union of two lists, removing duplicates.
Removes duplicate elements from a list based on the given equality module.
Functions
Concatenates a list of lists from left to right.
This uses the ListConcat monoid, preserving the original order of elements.
Examples
iex> Funx.List.concat([[1], [2, 3], [4]])
[1, 2, 3, 4]
@spec difference([term()], [term()], Funx.Eq.eq_t()) :: [term()]
Returns the difference of two lists.
Examples
iex> Funx.List.difference([1, 2, 3, 4], [3, 4, 5])
[1, 2]
@spec elem?([term()], term(), Funx.Eq.eq_t()) :: boolean()
Returns true if the given value is an element of the list under the provided Eq.
This is the Eq-based equivalent of Haskell's elem.
Examples
iex> Funx.List.elem?([1, 2, 3], 1)
true
iex> Funx.List.elem?([1, 3], 2)
false
@spec group([a], Funx.Eq.eq_t()) :: [[a]] when a: term()
Groups consecutive equal elements into sublists.
This is the Eq-based equivalent of Haskell's group.
Examples
iex> Funx.List.group([1, 1, 2, 2, 2, 3, 1, 1])
[[1, 1], [2, 2, 2], [3], [1, 1]]
iex> Funx.List.group([])
[]
iex> Funx.List.group([1])
[[1]]
@spec group_sort([a], Funx.Ord.ord_t()) :: [[a]] when a: term()
Sorts a list and then groups consecutive equal elements.
This combines sort/2 and group/2, using Ord for sorting and
deriving Eq from the ordering for grouping.
Examples
iex> Funx.List.group_sort([1, 2, 1, 2, 1])
[[1, 1, 1], [2, 2]]
iex> Funx.List.group_sort([])
[]
iex> Funx.List.group_sort([3, 1, 2, 1, 3])
[[1, 1], [2], [3, 3]]
@spec head([a]) :: Funx.Monad.Maybe.t(a) when a: term()
Returns the head of a list wrapped in Maybe.Just, or Maybe.Nothing if empty.
This is a safe version of hd/1 that returns Maybe instead of raising.
Examples
iex> Funx.List.head([1, 2, 3])
%Funx.Monad.Maybe.Just{value: 1}
iex> Funx.List.head([])
%Funx.Monad.Maybe.Nothing{}
iex> Funx.List.head("not a list")
%Funx.Monad.Maybe.Nothing{}
@spec head!([a]) :: a when a: term()
Returns the head of a list.
Raises ArgumentError if the list is empty or not a list.
Examples
iex> Funx.List.head!([1, 2, 3])
1
iex> Funx.List.head!([42])
42
@spec intersection([term()], [term()], Funx.Eq.eq_t()) :: [term()]
Returns the intersection of two lists.
Examples
iex> Funx.List.intersection([1, 2, 3, 4], [3, 4, 5])
[3, 4]
@spec max([a], Funx.Ord.ord_t()) :: Funx.Monad.Maybe.t(a) when a: term()
Returns the maximum element in a list according to the given ordering.
Returns Just(element) for non-empty lists, Nothing for empty lists.
This is a safe version that returns Maybe instead of raising.
Use max!/2 if you want to raise on empty lists.
Examples
iex> Funx.List.max([3, 1, 4, 1, 5])
%Funx.Monad.Maybe.Just{value: 5}
iex> Funx.List.max([])
%Funx.Monad.Maybe.Nothing{}
iex> ord = Funx.Ord.contramap(&String.length/1)
iex> Funx.List.max(["cat", "elephant", "ox"], ord)
%Funx.Monad.Maybe.Just{value: "elephant"}
@spec max!([a], Funx.Ord.ord_t()) :: a when a: term()
Returns the maximum element in a list according to the given ordering.
Raises Enum.EmptyError if the list is empty.
Examples
iex> Funx.List.max!([3, 1, 4, 1, 5])
5
iex> ord = Funx.Ord.contramap(&String.length/1)
iex> Funx.List.max!(["cat", "elephant", "ox"], ord)
"elephant"
@spec min([a], Funx.Ord.ord_t()) :: Funx.Monad.Maybe.t(a) when a: term()
Returns the minimum element in a list according to the given ordering.
Returns Just(element) for non-empty lists, Nothing for empty lists.
This is a safe version that returns Maybe instead of raising.
Use min!/2 if you want to raise on empty lists.
Examples
iex> Funx.List.min([3, 1, 4, 1, 5])
%Funx.Monad.Maybe.Just{value: 1}
iex> Funx.List.min([])
%Funx.Monad.Maybe.Nothing{}
iex> ord = Funx.Ord.contramap(&String.length/1)
iex> Funx.List.min(["cat", "elephant", "ox"], ord)
%Funx.Monad.Maybe.Just{value: "ox"}
@spec min!([a], Funx.Ord.ord_t()) :: a when a: term()
Returns the minimum element in a list according to the given ordering.
Raises Enum.EmptyError if the list is empty.
Examples
iex> Funx.List.min!([3, 1, 4, 1, 5])
1
iex> ord = Funx.Ord.contramap(&String.length/1)
iex> Funx.List.min!(["cat", "elephant", "ox"], ord)
"ox"
@spec partition([a], a, Funx.Eq.eq_t()) :: {[a], [a]} when a: term()
Partitions a list into elements equal to a value and elements not equal.
Returns a tuple {matching, non_matching} where matching contains all
elements equal to value under the provided Eq, and non_matching
contains the rest.
Examples
iex> Funx.List.partition([1, 2, 1, 3, 1], 1)
{[1, 1, 1], [2, 3]}
iex> Funx.List.partition([1, 2, 3], 4)
{[], [1, 2, 3]}
iex> Funx.List.partition([], 1)
{[], []}
@spec sort([term()], Funx.Ord.ord_t()) :: [term()]
Sorts a list using the given ordering module.
Examples
iex> Funx.List.sort([3, 1, 4, 1, 5])
[1, 1, 3, 4, 5]
@spec strict_sort([term()], Funx.Ord.ord_t()) :: [term()]
Sorts a list while ensuring uniqueness.
Examples
iex> Funx.List.strict_sort([3, 1, 4, 1, 5])
[1, 3, 4, 5]
@spec subset?([term()], [term()], Funx.Eq.eq_t()) :: boolean()
Checks if the first list is a subset of the second.
Examples
iex> Funx.List.subset?([1, 2], [1, 2, 3, 4])
true
iex> Funx.List.subset?([1, 5], [1, 2, 3, 4])
false
@spec superset?([term()], [term()], Funx.Eq.eq_t()) :: boolean()
Checks if the first list is a superset of the second.
Examples
iex> Funx.List.superset?([1, 2, 3, 4], [1, 2])
true
iex> Funx.List.superset?([1, 2, 3, 4], [1, 5])
false
@spec symmetric_difference([term()], [term()], Funx.Eq.eq_t()) :: [term()]
Returns the symmetric difference of two lists.
Examples
iex> Funx.List.symmetric_difference([1, 2, 3], [3, 4, 5])
[1, 2, 4, 5]
@spec tail([a]) :: [a] when a: term()
Returns the tail of a list.
The tail of an empty list is an empty list.
Examples
iex> Funx.List.tail([1, 2, 3])
[2, 3]
iex> Funx.List.tail([1])
[]
iex> Funx.List.tail([])
[]
@spec union([term()], [term()], Funx.Eq.eq_t()) :: [term()]
Returns the union of two lists, removing duplicates.
Examples
iex> Funx.List.union([1, 2, 3], [3, 4, 5])
[1, 2, 3, 4, 5]
@spec uniq([term()], Funx.Eq.eq_t()) :: [term()]
Removes duplicate elements from a list based on the given equality module.
Examples
iex> Funx.List.uniq([1, 2, 2, 3, 1, 4, 5])
[1, 2, 3, 4, 5]