Module transformers

Source
Expand description

Monad transformers and related utilities.

Monad transformers allow combining the effects of multiple monads, such as adding error handling to stateful computations or adding state to asynchronous operations.

§Monad Transformers

This module provides monad transformer implementations, which allow composing different monadic effects into a single monad. Monad transformers solve the problem of using multiple monads together without excessive nesting.

§What are Monad Transformers?

Monad transformers allow you to:

  • Combine multiple monadic effects (like option, state, reader, etc.)
  • Access the operations of all combined monads through a unified interface
  • Avoid deeply nested monadic types

§Core Concepts

The key components of the monad transformer pattern:

  • Base Monad: The innermost monad being transformed (e.g., Result, Option, Vec)
  • Transformer: A wrapper that adds new effects while preserving the interface
  • Lift: Operations to promote values from the base monad to the transformer
  • Stack: The combination of transformers and base monad creates a “stack” of effects

§Transformer Stacks

Transformers are typically used in stacks, with each transformer adding a new capability:

ReaderT<StateT<Option<_>>> = Environment + State + Optionality

In this example:

  • Option<_> is the base monad, providing optional computation
  • StateT<_> transforms it to add state management
  • ReaderT<_> adds environment access on top

§Available Transformers

This module provides the following monad transformers:

  • ReaderT: Adds environment capabilities

    • Makes an environment value available throughout a computation
    • Useful for dependency injection and configuration
  • StateT: Adds stateful computation capabilities

    • Allows passing and modifying state through a computation
    • Useful for tracking changing values without mutation
  • WriterT: Adds logging capabilities

    • Accumulates a log or other appendable data alongside computation
    • Useful for collecting messages, traces, or other output

§Implementation Pattern

Monad transformers generally follow this implementation pattern:

  1. Define a new type that wraps a function or value with the base monad inside
  2. Implement the MonadTransformer trait to provide lifting capabilities
  3. Implement the Monad trait to allow composition with other monads
  4. Provide additional methods specific to the transformer (like run, exec, etc.)

§Stacking Transformers

When stacking multiple transformers, you’ll need to lift values through each layer:

// If you have a base monad value:
let base_value: Option<T> = Some(value);

// Lift through multiple layers:
let value_in_state_reader_t = lift::<ReaderT<_, _, _>>(lift::<StateT<_, _, _>>(base_value));

§Performance Considerations

Monad transformers add some overhead due to their layered nature. Consider:

  • Each transformer adds a level of indirection
  • Deep stacks may impact performance in critical sections
  • More complex type signatures with multiple transformers

For performance-critical code, consider using specialized combined monads instead of deep transformer stacks.

Re-exports§

pub use cont_t::ContT;
pub use reader_t::ReaderT;
pub use state_t::StateT;

Modules§

cont_t
Continuation Monad Transformer (ContT)
reader_t
Reader Transformer
state_t
The State monad transformer, adding stateful computations to any monad.

Traits§

MonadTransformer
Trait for monad transformers.

Functions§

lift
Lifts a value from a base monad into a monad transformer.