Skip to main content

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::doc_params;
17use fp_macros::doc_type_params;
18use fp_macros::hm_signature;
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	#[hm_signature(Evaluable)]
30	///
31	/// ### Type Parameters
32	///
33	#[doc_type_params("The lifetime of the value.", "The type of the value inside the functor.")]
34	///
35	/// ### Parameters
36	///
37	#[doc_params("The functor instance to evaluate.")]
38	///
39	/// ### Returns
40	///
41	/// The inner value.
42	///
43	/// ### Examples
44	///
45	/// ```
46	/// use fp_library::{brands::*, functions::*, types::*};
47	///
48	/// let eval = Thunk::new(|| 42);
49	/// assert_eq!(evaluate::<ThunkBrand, _>(eval), 42);
50	/// ```
51	fn evaluate<'a, A: 'a>(fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)) -> A;
52}
53
54/// Evaluates the effect, producing the inner value.
55///
56/// Free function version that dispatches to [the type class' associated function][`Evaluable::evaluate`].
57///
58/// ### Type Signature
59///
60#[hm_signature(Evaluable)]
61///
62/// ### Type Parameters
63///
64#[doc_type_params(
65	"The lifetime of the value.",
66	"The evaluable functor.",
67	"The type of the value inside the functor."
68)]
69///
70/// ### Parameters
71///
72#[doc_params("The functor instance to evaluable.")]
73///
74/// ### Returns
75///
76/// The inner value.
77///
78/// ### Examples
79///
80/// ```
81/// use fp_library::{brands::*, functions::*, types::*};
82///
83/// let eval = Thunk::new(|| 42);
84/// assert_eq!(evaluate::<ThunkBrand, _>(eval), 42);
85/// ```
86pub fn evaluate<'a, F, A>(fa: Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)) -> A
87where
88	F: Evaluable,
89	A: 'a,
90{
91	F::evaluate(fa)
92}