Basic Effects in fx-rs
This section expands on Concepts and shows how they relate to the fx-rs
API, providing intuition on effect requirements and evaluation in Rust.
Fx<(), V>
: Immediate Effects
The most basic effects are immediate effects. These are of type Fx<(), V>
, meaning they have no ability requirements and evaluate to a value V
.
Immediate effects are created using Fx::pure(value)
or Fx::value(value)
.
A pure effect just holds an already known value instead of computing it.
The value can be retrieved by calling .eval()
on the effect. Only effects with no requirements (()
) can be evaluated directly.
#![allow(unused)] fn main() { use fx::Fx; // Type alias for a simple effect with no requirements type PureString = Fx<(), String>; let v = "Hello World".to_owned(); let effect: PureString = Fx::pure(v.clone()); let result: String = effect.eval(); assert_eq!(result, v); // result: String } }
Fx<S, V>
: Pending Effects
An effect Fx<S, V>
where S
is not ()
is a pending effect that needs S
to be provided before computing V
.
The most basic pending computation is a function. For example, a function from String
to usize
can be expressed as an effect of type Fx<String, usize>
:
#![allow(unused)] fn main() { use fx::Fx; fn length_of_string(s: String) -> usize { s.len() } fn func_example() { let effect: Fx<String, usize> = Fx::func(length_of_string); let requirement = "Hello World".to_owned(); let provided = effect.provide(requirement.clone()); let result = provided.eval(); assert_eq!(result, requirement.len()); } }
Fx::func(f)
produces a pending effect of typeFx<S, V>
from a functionf: S -> V
..provide(value)
discharges the requirement and returnsFx<(), V>
. No computation is performed until.eval()
is called..eval()
performs the computation, since all requirements have been provided.
These are the most basic effects in fx-rs
. More interesting effects are presented in later chapters.