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::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}