//@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,
}