fp_library/classes/
try_semigroup.rs

1//! A trait for types that can be combined fallibly.
2//!
3//! This is similar to `Semigroup`, but the combination operation returns a `Result`.
4//! This is useful for types like `Lazy` where combination might trigger evaluation
5//! that could fail (panic).
6//!
7//! ### Examples
8//!
9//! ```
10//! use fp_library::{brands::*, classes::*, functions::*};
11//!
12//! let x = String::from("Hello, ");
13//! let y = String::from("World!");
14//! let z = try_append(x, y);
15//! assert_eq!(z, Ok(String::from("Hello, World!")));
16//! ```
17
18use super::Semigroup;
19
20/// A trait for types that can be combined fallibly.
21///
22/// This is similar to [`Semigroup`], but the combination operation returns a `Result`.
23/// This is useful for types like `Lazy` where combination might trigger evaluation
24/// that could fail (panic).
25pub trait TrySemigroup: Sized {
26	/// The error type that can occur during combination.
27	type Error;
28
29	/// Fallibly combine two values.
30	///
31	/// ### Type Signature
32	///
33	/// `forall a. TrySemigroup a => (a, a) -> Result a a::Error`
34	///
35	/// ### Parameters
36	///
37	/// * `x`: The first value to combine.
38	/// * `y`: The second value to combine.
39	///
40	/// ### Returns
41	///
42	/// The result of combining `x` and `y`, or an error.
43	///
44	/// ### Examples
45	///
46	/// ```
47	/// use fp_library::{brands::*, classes::*, functions::*};
48	///
49	/// let x = String::from("Hello, ");
50	/// let y = String::from("World!");
51	/// let z = String::try_append(x, y);
52	/// assert_eq!(z, Ok(String::from("Hello, World!")));
53	/// ```
54	fn try_append(
55		x: Self,
56		y: Self,
57	) -> Result<Self, Self::Error>;
58}
59
60impl<T: Semigroup> TrySemigroup for T {
61	type Error = std::convert::Infallible;
62
63	fn try_append(
64		x: Self,
65		y: Self,
66	) -> Result<Self, Self::Error> {
67		Ok(<T as Semigroup>::append(x, y))
68	}
69}
70
71/// Fallibly combine two values.
72///
73/// Free function version that dispatches to [the type class' associated function][`TrySemigroup::try_append`].
74///
75/// ### Type Signature
76///
77/// `forall a. TrySemigroup a => (a, a) -> Result a a::Error`
78///
79/// ### Type Parameters
80///
81/// * `A`: The type of the values to combine.
82///
83/// ### Parameters
84///
85/// * `x`: The first value to combine.
86/// * `y`: The second value to combine.
87///
88/// ### Returns
89///
90/// The result of combining `x` and `y`, or an error.
91///
92/// ### Examples
93///
94/// ```
95/// use fp_library::{brands::*, classes::*, functions::*};
96///
97/// let x = String::from("Hello, ");
98/// let y = String::from("World!");
99/// let z = try_append(x, y);
100/// assert_eq!(z, Ok(String::from("Hello, World!")));
101/// ```
102pub fn try_append<A: TrySemigroup>(
103	x: A,
104	y: A,
105) -> Result<A, A::Error> {
106	A::try_append(x, y)
107}