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