cat/contravariant

Contravariant functor type {minimal implementation - contramap}.
Default implementations for: replace, replace_flip (>$ and $< operators), and phantom function.

Types

Contravariant type in gleam.

// Haskell type class
class Contravariant f where
    contramap :: (a -> b) -> f b -> f a

Contravariant laws:

  • Preservation of identity: contramap id = id
  • Preservation of composition: contramap (g ∘ h) = (contramap h) ∘ (contramap g)

See functor type for convention.

pub type Contravariant(f, a, b, fa, fb) {
  Contravariant(contramap: fn(fn(a) -> b) -> fn(fb) -> fa)
}

Constructors

  • Contravariant(contramap: fn(fn(a) -> b) -> fn(fb) -> fa)

Values

pub fn phantom(
  functor: functor.Functor(f, a, Nil, fa, b),
  contra: Contravariant(f, a, Nil, fb, b),
) -> fn(fa) -> fb

Haskell phantom function.

phantom :: (Functor f, Contravariant f) => f a => f b
phantom x = () <$ x $< ()

If f is both Functor and Contravariant, it can’t use its argument in a meaningful way. The laws follow from the preservation of composition for fmap and contramap.

Laws:

  • fmap f = phantom
  • contramap f = phantom

Examples

// Phantom type for the instance
pub type UnitF
// Construct two instances (functor and covariant) for the same type
let unit_functor: Functor(UnitF, _, _, _, Nil) =
    Functor(fmap: fn(_) { cat.unit })
let unit_contravariant: Contravariant(UnitF, _, _, Nil, _) =
    Contravariant(contramap: fn(_) { cat.unit })
// We are left with the instance UnitF
// According to the laws of composition for fmap and contramap, this type can't do anything
"abc"
|> phantom(unit_functor, unit_contravariant)
// -> Nil
pub fn replace(
  contravar: Contravariant(c, a, b, fa, fb),
) -> fn(b, fb) -> fa

Haskell (>$) operator.

(>$) :: b -> f b -> f a
(>$) = contramap ∘ const

Examples

let o = con.Op(int.to_string)
// Doesn't matter what value/type we send to the final apply  
True
|> replace(op_contravariant())(7, o).apply
// -> "7"
pub fn replace_flip(
  contravar: Contravariant(c, a, b, fa, fb),
) -> fn(fb, b) -> fa

Haskell ($<) operator.

($<) :: f b -> b -> f a
($<) = flip(>$)

Examples

let o = con.Op(int.to_string)
// Doesn't matter what value/type we use for the final apply  
[1, 2, 3]
|> replace_flip(op_contravariant())(o, 7).apply
// -> "7"
Search Document