Skip to main content

RefMonad

Trait RefMonad 

Source
pub trait RefMonad: RefApplicative + RefSemimonad { }
Expand description

A type class for by-ref monads.

Combines RefApplicative (by-ref pure + apply) with RefSemimonad (by-ref bind).

This is the by-ref counterpart of Monad. Automatically implemented for any type implementing both supertraits.

A lawful RefMonad must satisfy three laws:

  1. Left identity: bind(ref_pure(&a), f) evaluates to the same value as f(&a).
  2. Right identity: bind(m, |x| ref_pure(x)) evaluates to the same value as m.
  3. Associativity: bind(bind(m, f), g) evaluates to the same value as bind(m, |x| bind(f(x), g)).

These are the standard monad laws expressed with by-ref operations. Equality is by evaluated value, not structural identity, since memoized types like Lazy create new allocations on each construction.

§Examples

use fp_library::{
	brands::*,
	classes::*,
	functions::{
		explicit::bind,
		*,
	},
	types::*,
};

let f = |x: &i32| {
	let v = *x + 1;
	Lazy::<_, RcLazyConfig>::new(move || v)
};
let g = |x: &i32| {
	let v = *x * 2;
	Lazy::<_, RcLazyConfig>::new(move || v)
};

// Left identity: bind(ref_pure(&a), f) = f(&a)
let left =
	bind::<LazyBrand<RcLazyConfig>, _, _, _, _>(&ref_pure::<LazyBrand<RcLazyConfig>, _>(&5), f);
assert_eq!(*left.evaluate(), *f(&5).evaluate());

// Right identity: bind(m, |x| ref_pure(x)) = m
let m = RcLazy::pure(42);
let right = bind::<LazyBrand<RcLazyConfig>, _, _, _, _>(&m, |x: &i32| {
	ref_pure::<LazyBrand<RcLazyConfig>, _>(x)
});
assert_eq!(*right.evaluate(), *m.evaluate());

// Associativity: bind(bind(m, f), g) = bind(m, |x| bind(f(x), g))
let m = RcLazy::pure(3);
let lhs = bind::<LazyBrand<RcLazyConfig>, _, _, _, _>(
	&bind::<LazyBrand<RcLazyConfig>, _, _, _, _>(&m, f),
	g,
);
let rhs = bind::<LazyBrand<RcLazyConfig>, _, _, _, _>(&m, |x: &i32| {
	bind::<LazyBrand<RcLazyConfig>, _, _, _, _>(&f(x), g)
});
assert_eq!(*lhs.evaluate(), *rhs.evaluate());

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl<Brand> RefMonad for Brand

Blanket implementation of RefMonad.

§Type Parameters
  • Brand: The brand type.