cat/natural

NaturalTransformation type {minimal implementation transform}.
Composition function with a few examples of natural transformations between functors.

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 opaque type NaturalTransformation(f, g, fa, ga)

Functions

pub fn ffmap(
  alpha: NaturalTransformation(Functor(a, b, c, d, e), f, g, h),
) -> fn(fn(b) -> c) -> fn(d) -> e

Getter for the fmap of f of NaturalTransformation.

pub fn gfmap(
  alpha: NaturalTransformation(a, Functor(b, c, d, e, f), g, h),
) -> fn(fn(c) -> d) -> fn(e) -> f

Getter for the fmap of g of NaturalTransformation.

pub fn horizontal_composition(
  alpha: NaturalTransformation(
    Functor(a, b, c, d, e),
    Functor(f, b, c, g, h),
    d,
    g,
  ),
  beta: NaturalTransformation(
    Functor(i, j, k, l, m),
    Functor(n, j, k, o, p),
    l,
    o,
  ),
) -> NaturalTransformation(
  Functor(Pair(a, i), b, c, q, r),
  Functor(Pair(f, n), b, c, s, t),
  q,
  t,
)

Deprecated: Imposible to implement

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)

Due to gleam’s type system, we cannot implement this generic function

pub fn list_length_transformation() -> NaturalTransformation(
  Functor(ListF, a, b, List(a), List(b)),
  Functor(ConstF(c), d, e, Const(c, d), Const(c, e)),
  List(a),
  Const(Int, f),
)

Natural transformation from List to Const Int.

Examples

[]
|> {list_length_transformation() |> transform()}
// -> Const(0)
[1, 2, 3, 4]
|> {list_length_transformation() |> transform()}
// -> Const(4)
pub fn list_option_head_transformation() -> NaturalTransformation(
  Functor(ListF, a, b, List(a), List(b)),
  Functor(OptionF, c, d, Option(c), Option(d)),
  List(a),
  Option(a),
)

Natural transformation from List to Option.

Examples

[]
|> {list_option_head_transformation() |> transform()}
// -> None
[1, 2, 3]
|> {list_option_head_transformation() |> transform()}
// -> Some(1)
pub fn new(
  f: fn() -> Functor(a, b, c, d, e),
  g: fn() -> Functor(f, g, h, i, j),
  transform: fn(d) -> k,
) -> NaturalTransformation(
  Functor(a, b, c, d, e),
  Functor(f, g, h, i, j),
  d,
  k,
)

Smart constructor for the NaturalTransformation type.
Takes two functor instance generation (so that the types stay generic) and a transform function.

pub fn option_list_transformation() -> NaturalTransformation(
  Functor(OptionF, a, b, Option(a), Option(b)),
  Functor(ListF, c, d, List(c), List(d)),
  Option(a),
  List(a),
)

Natural transformation from Option to List.

Examples

None
|> {option_list_transformation() |> transform()}
// -> []
Some(7)
|> {option_list_transformation() |> transform()}
// -> [7]
pub fn transform(
  alpha: NaturalTransformation(a, b, c, d),
) -> fn(c) -> d

Getter for the transform field of NaturalTransformation.

pub fn vertical_composition(
  alpha: NaturalTransformation(a, b, c, d),
  beta: NaturalTransformation(b, e, d, f),
) -> NaturalTransformation(a, e, c, f)

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)
Search Document