fp_library/classes/pipe.rs
1//! Left-to-right function application via method syntax.
2//!
3//! Provides the [`Pipe`] trait for pipeline-style composition, similar to
4//! PureScript's `#` operator or Haskell's `&` operator.
5//!
6//! ### Examples
7//!
8//! ```
9//! use fp_library::{
10//! brands::*,
11//! classes::*,
12//! functions::*,
13//! };
14//!
15//! let result = Some(5).pipe(|x| map::<OptionBrand, _, _>(|n| n + 1, x));
16//!
17//! assert_eq!(result, Some(6));
18//! ```
19
20#[fp_macros::document_module]
21mod inner {
22 use fp_macros::*;
23
24 /// A trait for left-to-right function application via method syntax.
25 ///
26 /// `Pipe` provides the `.pipe()` method on all sized types via a blanket
27 /// implementation, enabling pipeline-style composition similar to
28 /// PureScript's `#` operator or Haskell's `&` operator.
29 ///
30 /// This is particularly useful for composing operations on types where
31 /// inherent methods are not available (e.g., stdlib types like `Option`
32 /// and `Vec`).
33 #[document_parameters("The value to pipe.")]
34 pub trait Pipe: Sized {
35 /// Pipes `self` into a function, enabling left-to-right composition.
36 ///
37 /// Applies `f` to `self` and returns the result. This is the method
38 /// syntax version of [`pipe`].
39 #[document_signature]
40 ///
41 #[document_type_parameters("The return type of the function.")]
42 ///
43 #[document_parameters("The function to apply to the value.")]
44 ///
45 #[document_returns("The result of applying `f` to `self`.")]
46 #[document_examples]
47 ///
48 /// ```
49 /// use fp_library::{
50 /// brands::*,
51 /// classes::*,
52 /// functions::*,
53 /// };
54 ///
55 /// let result = Some(5)
56 /// .pipe(|x| map::<OptionBrand, _, _>(|n| n + 1, x))
57 /// .pipe(|x| bind::<OptionBrand, _, _>(x, |n| if n > 3 { Some(n) } else { None }));
58 ///
59 /// assert_eq!(result, Some(6));
60 /// ```
61 fn pipe<B>(
62 self,
63 f: impl FnOnce(Self) -> B,
64 ) -> B {
65 f(self)
66 }
67 }
68
69 #[document_type_parameters("The type that implements Pipe.")]
70 impl<T> Pipe for T {}
71
72 /// Pipes a value into a function, enabling left-to-right composition.
73 ///
74 /// Free function version of [`Pipe::pipe`]. Applies `f` to `a` and
75 /// returns the result. This is equivalent to PureScript's `applyFlipped`
76 /// or Haskell's `(&)`.
77 #[document_signature]
78 ///
79 #[document_type_parameters("The type of the input value.", "The return type of the function.")]
80 ///
81 #[document_parameters("The value to pipe.", "The function to apply to the value.")]
82 ///
83 #[document_returns("The result of applying `f` to `a`.")]
84 #[document_examples]
85 ///
86 /// ```
87 /// use fp_library::functions::*;
88 ///
89 /// let result = pipe(5, |x| x + 1);
90 /// assert_eq!(result, 6);
91 /// ```
92 pub fn pipe<A, B>(
93 a: A,
94 f: impl FnOnce(A) -> B,
95 ) -> B {
96 f(a)
97 }
98}
99
100pub use inner::*;