cat/natural
NaturalTransformation
type {minimal implementation transform
}.
Composition
function.
Types
A natural transformation of two functors
F and G is a collection of functions such that for every type a we have a function (component
) that goes from F a to G a.
This implementation in gleam is a bit more restrictive in that each component
is an instantiation of the generic
function transform for the type a.
Examples
A natural transformation from Option
to List
will contain a transform
function that, for any type a
, takes an Option(a)
and returns a List(a)
.
transform: fn(Option(a)) -> List(a)
pub type NaturalTransformation(f, g, a, b, fa, fb, c, d, gc, gd) {
NaturalTransformation(
f: functor.Functor(f, a, b, fa, fb),
g: functor.Functor(g, c, d, gc, gd),
transform: fn(fa) -> gc,
)
}
Constructors
-
NaturalTransformation( f: functor.Functor(f, a, b, fa, fb), g: functor.Functor(g, c, d, gc, gd), transform: fn(fa) -> gc, )
Values
pub fn horizontal_composition(
alpha: NaturalTransformation(f1, f2, a, b, c, d, e, f, d, g),
beta: NaturalTransformation(g1, g2, c, d, h, h, d, g, i, j),
) -> NaturalTransformation(
cat.Pair(g1, f1),
cat.Pair(g2, f2),
a,
b,
h,
h,
e,
f,
i,
j,
)
Horizontal composition
∘ of two natural transformations
.
alpha_a :: F a -> F' a
beta_a :: G a -> G' a
// These transformation compose:
beta ∘ alpha :: G ∘ F -> G' ∘ F'
(beta ∘ alpha)_a = G' (alpha_a) ∘ beta_Fa = beta_F'a ∘ G (alpha_a)
Unfortunately Gleam coerces f1 = f2 because g1 is bound to a type ‘f1 a’ and is not truly generic (we need g1 to contain both ‘f1 a’ and ‘f2 a’ but the types are bound in the argument list)
pub fn vertical_composition(
alpha: NaturalTransformation(f, g, a, b, fa, fb, c, d, gc, gd),
beta: NaturalTransformation(g, h, c, d, gc, gd, x, y, hx, hy),
) -> NaturalTransformation(f, h, a, b, fa, fb, x, y, hx, hy)
Vertical composition
⋅ of two natural transformations
.
alpha_a :: F a -> G a
beta_a :: G a -> H a
// These morphisms compose:
beta_a ∘ alpha_a :: F a -> H a
// So the natural transformations also compose:
(beta ⋅ alpha)_a = beta_a ∘ alpha_a
Examples
let maybe_const =
vertical_composition(
option_list_transformation(),
list_length_transformation()
)
None
|> transform(maybe_const)
// -> Const(0)
Some("abc")
|> transform(maybe_const)
// -> Const(1)