Skip to main content

fp_library/types/
last.rs

1//! A newtype wrapper whose [`Semigroup`](crate::classes::Semigroup) instance always keeps the last
2//! (rightmost) value.
3//!
4//! ### Examples
5//!
6//! ```
7//! use fp_library::{
8//! 	functions::*,
9//! 	types::Last,
10//! };
11//!
12//! assert_eq!(append(Last(1), Last(2)), Last(2));
13//! ```
14
15#[fp_macros::document_module]
16mod inner {
17	use {
18		crate::classes::*,
19		fp_macros::*,
20	};
21
22	/// A newtype wrapper whose [`Semigroup`] instance always keeps the last value.
23	///
24	/// `append(Last(a), Last(b))` returns `Last(b)`, discarding `a`.
25	///
26	/// There is no [`Monoid`] instance because there is no identity element.
27	#[document_examples]
28	///
29	/// ```
30	/// use fp_library::{
31	/// 	functions::*,
32	/// 	types::Last,
33	/// };
34	///
35	/// assert_eq!(append(Last("hello"), Last("world")), Last("world"));
36	/// ```
37	#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
38	pub struct Last<A>(
39		/// The wrapped value.
40		pub A,
41	);
42
43	#[document_type_parameters("The wrapped type.")]
44	impl<A> Semigroup for Last<A> {
45		/// Returns the last (rightmost) value, discarding the first.
46		#[document_signature]
47		///
48		#[document_parameters("The first value (discarded).", "The second value (kept).")]
49		///
50		#[document_returns("The second value.")]
51		#[document_examples]
52		///
53		/// ```
54		/// use fp_library::{
55		/// 	functions::*,
56		/// 	types::Last,
57		/// };
58		///
59		/// assert_eq!(append(Last(1), Last(2)), Last(2));
60		/// ```
61		fn append(
62			_a: Self,
63			b: Self,
64		) -> Self {
65			b
66		}
67	}
68}
69
70pub use inner::*;
71
72#[cfg(test)]
73mod tests {
74	use {
75		super::*,
76		crate::functions::*,
77		quickcheck_macros::quickcheck,
78	};
79
80	#[quickcheck]
81	fn semigroup_associativity(
82		a: i32,
83		b: i32,
84		c: i32,
85	) -> bool {
86		let x = Last(a);
87		let y = Last(b);
88		let z = Last(c);
89		append(x, append(y, z)) == append(append(x, y), z)
90	}
91}