What if learning was in scope?
A solid foundation built not just for use—but for understanding, mastery, and real growth.
Add Funx to your mix.exs dependencies:
Then run: mix deps.get
Don't just read—practice. Use Livebooks to experiment, try patterns with live code, and check your understanding.
Launch LivebooksEvery module includes comprehensive usage rules designed specifically for LLMs. Your AI assistant can explain, not just suggest—keeping answers grounded in your code context.
Pipeline-friendly syntax for operations that can fail. Safe, ergonomic, and declarative.
Elixir developers love pipelines, but traditional pipes break down with branching functions that return
{:ok, value} or
{:error, reason}.
The common solution—using bang functions (!)—sacrifices safety for ergonomics.
Get both safety and ergonomics. Write declarative pipelines that surface intent while handling errors gracefully.
Safe, ergonomic, and pipeline-friendly.
# Might crash!
assignment = Ash.get!(Assignment, id)
case close_assignment(assignment) do
{:ok, updated} ->
Ash.load!(updated, [:status])
{:error, error} ->
{:error, error}
end
use Funx.Monad.Either
either Assignment, as: :tuple do
bind Ash.get(id)
bind close_assignment()
bind Ash.load([:status])
end
Write error-handling code that surfaces intent, not implementation details.
Handles plain values, result tuples, and Either values automatically.
Short-circuits on the first error, no unnecessary computation.
Choose Either, tuple, or raise formats with as: option.
Warns when using bind vs map incorrectly.
Chain operations that return branching types naturally.
bind
Chain operations that can fail (return Either or result tuples)
map
Transform values with functions that always succeed
ap
Apply functions wrapped in Either to values wrapped in Either
validate
Collect all validation errors from multiple validators
Either functions: filter_or_else, or_else, map_left, flip
"Surface intent over implementation—focus on what your code does, not how the machinery works."
These modules are ordered so each builds on the last. Start with Eq/Ord, then move through monoids, predicates, and monads.
Define what "equal" means for your domain:
Structured ordering without built-in operators:
Encapsulate computations and chain operations while handling different concerns:
Optional data with Just and Nothing
Two possibilities with Left and Right
Deferred execution with error handling
Pass environment for dependency injection
Thread logs alongside results using monoids
Simple wrapper for organizing transformations
Combine values with associative operations and identity elements: