fp_library/classes/applicative.rs
1//! Applicative functors.
2//!
3//! This module defines the [`Applicative`] trait, which extends [`Pointed`] and [`Semiapplicative`].
4//! Applicative functors allow for values to be wrapped in a context and for functions within a context to be applied to values within a context.
5
6use super::{
7 apply_first::ApplyFirst, apply_second::ApplySecond, pointed::Pointed,
8 semiapplicative::Semiapplicative,
9};
10
11/// A type class for applicative functors.
12///
13/// `Applicative` extends [`Pointed`] and [`Semiapplicative`].
14/// It allows for values to be wrapped in a context and for functions within a context to be applied to values within a context.
15///
16/// ### Type Signature
17///
18/// `class (Pointed f, Semiapplicative f) => Applicative f`
19///
20/// ### Examples
21///
22/// ```
23/// use fp_library::classes::applicative::Applicative;
24/// use fp_library::classes::pointed::pure;
25/// use fp_library::classes::semiapplicative::apply;
26/// use fp_library::classes::clonable_fn::ClonableFn;
27/// use fp_library::brands::OptionBrand;
28/// use fp_library::brands::RcFnBrand;
29///
30/// // Applicative combines Pointed (pure) and Semiapplicative (apply)
31/// let f = pure::<OptionBrand, _>(<RcFnBrand as ClonableFn>::new(|x: i32| x * 2));
32/// let x = pure::<OptionBrand, _>(5);
33/// let y = apply::<RcFnBrand, OptionBrand, _, _>(f, x);
34/// assert_eq!(y, Some(10));
35/// ```
36pub trait Applicative: Pointed + Semiapplicative + ApplyFirst + ApplySecond {}
37
38impl<Brand> Applicative for Brand where Brand: Pointed + Semiapplicative + ApplyFirst + ApplySecond {}