fp_library/classes/ref_pointed.rs
1//! Contexts that can be initialized from a reference via the [`ref_pure`] operation.
2//!
3//! Unlike [`Pointed::pure`](crate::classes::Pointed::pure), which takes ownership of
4//! the value, `ref_pure` accepts a reference and clones the value to produce the
5//! context. This enables by-reference generic code to construct contexts without
6//! requiring ownership.
7//!
8//! ### Examples
9//!
10//! ```
11//! use fp_library::{
12//! brands::*,
13//! classes::*,
14//! types::*,
15//! };
16//!
17//! let value = 42;
18//! let lazy = LazyBrand::<RcLazyConfig>::ref_pure(&value);
19//! assert_eq!(*lazy.evaluate(), 42);
20//! ```
21
22#[fp_macros::document_module]
23mod inner {
24 use {
25 crate::kinds::*,
26 fp_macros::*,
27 };
28
29 /// A type class for contexts that can be initialized from a reference.
30 ///
31 /// The `Clone` bound on `A` is required because constructing an owned
32 /// `Of<A>` from `&A` inherently requires cloning. This is the only
33 /// by-reference trait with a `Clone` bound; all other by-ref traits
34 /// pass `&A` to a user-supplied closure, letting the user control
35 /// whether cloning happens.
36 #[kind(type Of<'a, A: 'a>: 'a;)]
37 pub trait RefPointed {
38 /// Wraps a cloned value in the context.
39 #[document_signature]
40 ///
41 #[document_type_parameters(
42 "The lifetime of the value.",
43 "The type of the value to wrap. Must be `Clone`."
44 )]
45 ///
46 #[document_parameters("A reference to the value to wrap.")]
47 ///
48 #[document_returns("A new context containing a clone of the value.")]
49 #[document_examples]
50 ///
51 /// ```
52 /// use fp_library::{
53 /// brands::*,
54 /// classes::*,
55 /// types::*,
56 /// };
57 ///
58 /// let value = 42;
59 /// let lazy = LazyBrand::<RcLazyConfig>::ref_pure(&value);
60 /// assert_eq!(*lazy.evaluate(), 42);
61 /// ```
62 fn ref_pure<'a, A: Clone + 'a>(
63 a: &A
64 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>);
65 }
66
67 /// Wraps a cloned value in the context.
68 ///
69 /// Free function version that dispatches to [the type class' associated function][`RefPointed::ref_pure`].
70 #[document_signature]
71 ///
72 #[document_type_parameters(
73 "The lifetime of the value.",
74 "The brand of the context.",
75 "The type of the value to wrap. Must be `Clone`."
76 )]
77 ///
78 #[document_parameters("A reference to the value to wrap.")]
79 ///
80 #[document_returns("A new context containing a clone of the value.")]
81 #[document_examples]
82 ///
83 /// ```
84 /// use fp_library::{
85 /// brands::*,
86 /// functions::*,
87 /// types::*,
88 /// };
89 ///
90 /// let value = 42;
91 /// let lazy = ref_pure::<LazyBrand<RcLazyConfig>, _>(&value);
92 /// assert_eq!(*lazy.evaluate(), 42);
93 /// ```
94 pub fn ref_pure<'a, Brand: RefPointed, A: Clone + 'a>(
95 a: &A
96 ) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
97 Brand::ref_pure(a)
98 }
99}
100
101pub use inner::*;