View Source Funx.Monad.Either.Dsl.Transformer behaviour (funx v0.3.0)
Behaviour for transforming Either DSL pipelines after parsing.
Transformers allow post-parse optimization and validation of the pipeline. They receive a list of Step structs and can modify, validate, or optimize them.
Compile-Time Dependencies
⚠️ Transformers run at compile time and create compile-time dependencies.
When you use a transformer:
either user_id, transformers: [MyTransformer] do
bind GetUser
endThe MyTransformer.transform/2 function is called during macro expansion.
This means:
- The transformer output is baked into the compiled code
- Changes to the transformer may require recompiling modules that use it
- Run
mix clean && mix compileif transformer changes aren't reflected
This is intentional and allows for compile-time optimization. The DSL
uses Code.ensure_compiled!/1 to track these dependencies, so most changes
will trigger automatic recompilation.
Example
defmodule ValidateNoBareModules do
@behaviour Funx.Monad.Either.Dsl.Transformer
alias Funx.Monad.Either.Dsl.Step
@impl true
def transform(steps, _opts) do
# Validate that no steps use bare module atoms without options
case find_bare_module(steps) do
nil -> {:ok, steps}
bad_step -> {:error, "Step #{inspect(bad_step)} should use {Module, opts} syntax"}
end
end
defp find_bare_module(steps) do
Enum.find(steps, fn
%Step.Bind{operation: op} when is_atom(op) -> true
%Step.Map{operation: op} when is_atom(op) -> true
_ -> false
end)
end
endBuilt-in Transformers
Currently, no built-in transformers are provided. Transformers are opt-in and can be created for project-specific optimizations or validations.
Usage
Transformers are applied automatically during pipeline compilation.
They can be configured via the :transformers option:
either input, transformers: [MyTransformer] do
bind SomeModule
end
Summary
Callbacks
Transform a list of Step structs.
Functions
Apply a list of transformers to steps in order.
Types
@type error() :: {:error, String.t() | Exception.t()}
@type opts() :: keyword()
@type steps() :: [Funx.Monad.Either.Dsl.Step.t()]
Callbacks
Transform a list of Step structs.
Receives the parsed steps and any user options, and returns either:
{:ok, transformed_steps}- Modified steps{:error, message}- Validation error (raises CompileError)
The transformer can:
- Optimize steps (remove redundant operations)
- Validate cross-step constraints
- Add implicit steps
- Rewrite patterns into more efficient forms
Functions
Apply a list of transformers to steps in order.
Returns {:ok, steps} if all transformers succeed, or the first error.