fp_library/classes/evaluable.rs
1//! Functors whose effects can be evaluated to produce an inner value.
2//!
3//! This trait is used by [`Free::evaluate`](crate::types::Free::evaluate) to execute the effects
4//! in a [`Free`](crate::types::Free) monad.
5//!
6//! ### Examples
7//!
8//! ```
9//! use fp_library::{brands::*, functions::*, types::*};
10//!
11//! let thunk = Thunk::new(|| 42);
12//! assert_eq!(evaluate::<ThunkBrand, _>(thunk), 42);
13//! ```
14
15use crate::{Apply, classes::functor::Functor, kinds::*};
16use fp_macros::document_parameters;
17use fp_macros::document_signature;
18use fp_macros::document_type_parameters;
19
20/// A functor whose effects can be evaluated to produce the inner value.
21///
22/// This trait is used by [`Free::evaluate`](crate::types::Free::evaluate) to execute the effects
23/// in a [`Free`](crate::types::Free) monad.
24pub trait Evaluable: Functor {
25 /// Evaluates the effect, producing the inner value.
26 ///
27 /// ### Type Signature
28 ///
29 #[document_signature]
30 ///
31 /// ### Type Parameters
32 ///
33 #[document_type_parameters(
34 "The lifetime of the value.",
35 "The type of the value inside the functor."
36 )]
37 ///
38 /// ### Parameters
39 ///
40 #[document_parameters("The functor instance to evaluate.")]
41 ///
42 /// ### Returns
43 ///
44 /// The inner value.
45 ///
46 /// ### Examples
47 ///
48 /// ```
49 /// use fp_library::{brands::*, functions::*, types::*};
50 ///
51 /// let eval = Thunk::new(|| 42);
52 /// assert_eq!(evaluate::<ThunkBrand, _>(eval), 42);
53 /// ```
54 fn evaluate<'a, A: 'a>(fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)) -> A;
55}
56
57/// Evaluates the effect, producing the inner value.
58///
59/// Free function version that dispatches to [the type class' associated function][`Evaluable::evaluate`].
60///
61/// ### Type Signature
62///
63#[document_signature]
64///
65/// ### Type Parameters
66///
67#[document_type_parameters(
68 "The lifetime of the value.",
69 "The evaluable functor.",
70 "The type of the value inside the functor."
71)]
72///
73/// ### Parameters
74///
75#[document_parameters("The functor instance to evaluable.")]
76///
77/// ### Returns
78///
79/// The inner value.
80///
81/// ### Examples
82///
83/// ```
84/// use fp_library::{brands::*, functions::*, types::*};
85///
86/// let eval = Thunk::new(|| 42);
87/// assert_eq!(evaluate::<ThunkBrand, _>(eval), 42);
88/// ```
89pub fn evaluate<'a, F, A>(fa: Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)) -> A
90where
91 F: Evaluable,
92 A: 'a,
93{
94 F::evaluate(fa)
95}