Deep Causality HAFT
HAFT: Higher-Order Abstract Functional Traits
deep_causality_haft is a sub-crate of the deep_causality project, providing traits for Higher-Kinded Types (HKTs) in Rust. This enables writing generic, abstract code that can operate over different container types like Option<T> and Result<T, E>.
What are Higher-Kinded Types?
In Rust, types like Option<T> and Vec<T> are generic over a type T. We can think of Option and Vec as "type constructors": they take a type and produce a new type.
A Higher-Kinded Type is an abstraction over these type constructors. It allows us to write functions that are generic not just over a type, but over the shape or kind of a type constructor. For example, we can write a function that works with any type constructor that can be mapped over (a Functor), without caring if it's an Option, a Result, or something else.
This crate provides the fundamental traits (HKT, HKT2, HKT3) and functional traits (Functor, Monad) to enable this pattern.
Usage
This crate uses a "witness" pattern to represent HKTs. For each type constructor (like Option), we define a zero-sized "witness" type (like OptionWitness) that implements the HKT trait.
Example: Using Functor with Option
Here's how you can use the Functor trait with Option via its witness type, OptionWitness.
use ;
// Manual implementation of Functor for OptionWitness
Example: Using Functor with Result
Here's how you can use the Functor trait with Result<T, E> via its witness type, ResultWitness<E>. HKT2 is used here because Result has two generic parameters, and we are fixing the error type E.
use ;
// Manual implementation of Functor for ResultWitness
Type-Encoded Effect System
The Effect3 and MonadEffect3 traits provide a powerful mechanism for building a type-encoded effect system. This allows you to manage side-effects (like errors and logging) in a structured, safe, and composable way, which is particularly useful for building complex data processing pipelines.
How it Works
- Effects as Types: Side-effects are represented by generic type parameters on a container (e.g.,
Efor Error,Wfor Warning on a customMyEffect<T, E, W>type). - Rules as Traits: The logic for how to handle and combine these effects is defined by implementing the
MonadEffect3trait. For example, thebindfunction can specify that the pipeline should halt on an error while accumulating warnings. - Compiler-Enforced Safety: Because the effects are part of the type signature, the Rust compiler can statically verify that all effects are handled correctly. This prevents bugs and ensures that your pipeline code remains pure and focused on its core logic.
- Extensibility: This pattern is extensible. If you need to manage more side-effects, you can introduce
HKT4andEffect4traits to handle them, without having to rewrite your core pipeline logic.