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::*;