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