gluon 0.18.2

A static, type inferred programming language for application embedding
Documentation
//@NO-IMPLICIT-PRELUDE
//! Implementation of the `Applicative` type

let { Bool } = import! std.types
let { Functor, map } = import! std.functor

/// A `Functor` with application.
///
/// The following laws should hold:
///
/// * `wrap id <*> v = v`
/// * `wrap (<<) <*> u <*> v <*> w = u <*> (v <*> w)`
/// * `wrap f <*> wrap x = wrap (f x)`
/// * `u <*> wrap y = wrap (\g -> g x) <*> u`
#[implicit]
type Applicative (f : Type -> Type) = {
    functor : Functor f,
    /// Like `functor.map`, but this time the supplied function is embedded in `f`
    ///
    /// # Note
    ///
    /// * Known as `(<*>)` in Haskell
    apply : forall a b . f (a -> b) -> f a -> f b,
    /// Wrap the supplied value in `f`
    ///
    /// # Examples
    ///
    /// * `option.applicative.wrap 1 == Some 1`
    /// * `result.applicative.wrap 1 == Ok 1`
    /// * `list.applicative.wrap 1 == list.of [1]`
    ///
    /// # Note
    ///
    /// * Known as `pure` in Haskell
    wrap : forall a . a -> f a
}

let wrap ?app : [Applicative f] -> a -> f a = app.wrap
let apply ?app : [Applicative f] -> f (a -> b) -> f a -> f b = app.apply

/// Alias of `<*>`
#[infix(left, 4)]
let (<*>) : [Applicative f] -> f (a -> b) -> f a -> f b = apply

/// Sequence actions, discarding the value of the second argument
#[infix(left, 4)]
let (<*) l r : [Applicative f] -> f a -> f b -> f a = map (\x _ -> x) l <*> r

/// Sequence actions, discarding the value of the first argument
#[infix(left, 4)]
let (*>) l r : [Applicative f] -> f a -> f b -> f b = map (\_ x -> x) l <*> r

/// Maps over two actions
let map2 fn a b : [Applicative f]
        -> (a -> b -> c)
        -> f a
        -> f b
        -> f c
    =
    map fn a <*> b

/// Maps over three actions
let map3 fn a b c : [Applicative f] -> (a -> b -> c -> d) -> f a -> f b -> f c -> f d =
    map2 fn a b <*> c

let map4 fn a b c d : [Applicative f] -> _ =
    map3 fn a b c <*> d

let map5 fn a b c d e : [Applicative f] -> _ =
    map4 fn a b c d <*> e

let map6 fn a b c d e f : [Applicative f] -> _ =
    map5 fn a b c d e <*> f

let map7 fn a b c d e f g : [Applicative f] -> _ =
    map6 fn a b c d e f <*> g

let map8 fn a b c d e f g h : [Applicative f] -> _ =
    map7 fn a b c d e f g <*> h

let map9 fn a b c d e f g h i : [Applicative f] -> _ =
    map8 fn a b c d e f g h <*> i

let map10 fn a b c d e f g h i j : [Applicative f] -> _ =
    map9 fn a b c d e f g h i <*> j

let when b m : [Applicative m] -> Bool -> m () -> m () =
    if b then m
    else wrap ()

{
    Applicative,
    apply,
    wrap,
    (<*>),
    (<*),
    (*>),

    map2,
    map3,
    map4,
    map5,
    map6,
    map7,
    map8,
    map9,
    map10,

    when,
}