Skip to main content

fp_library/classes/
runnable.rs

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