1#[fp_macros::document_module]
18mod inner {
19 use {
20 crate::classes::*,
21 fp_macros::*,
22 };
23
24 #[document_examples]
31 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
43 #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
44 pub struct Dual<A>(
45 pub A,
47 );
48
49 #[document_type_parameters("The semigroup type.")]
50 impl<A: Semigroup> Semigroup for Dual<A> {
51 #[document_signature]
55 #[document_parameters("The first dual value.", "The second dual value.")]
57 #[document_returns("The reversed combination wrapped in `Dual`.")]
59 #[document_examples]
60 fn append(
70 a: Self,
71 b: Self,
72 ) -> Self {
73 Dual(A::append(b.0, a.0))
74 }
75 }
76
77 #[document_type_parameters("The monoid type.")]
78 impl<A: Monoid> Monoid for Dual<A> {
79 #[document_signature]
81 #[document_returns("The identity element wrapped in `Dual`.")]
83 #[document_examples]
84 fn empty() -> Self {
94 Dual(A::empty())
95 }
96 }
97}
98
99pub use inner::*;
100
101#[cfg(test)]
102mod tests {
103 use {
104 super::*,
105 crate::functions::*,
106 quickcheck_macros::quickcheck,
107 };
108
109 #[quickcheck]
110 fn semigroup_associativity(
111 a: String,
112 b: String,
113 c: String,
114 ) -> bool {
115 let x = Dual(a);
116 let y = Dual(b);
117 let z = Dual(c);
118 append(x.clone(), append(y.clone(), z.clone())) == append(append(x, y), z)
119 }
120
121 #[quickcheck]
122 fn monoid_left_identity(a: String) -> bool {
123 let x = Dual(a);
124 append(empty::<Dual<String>>(), x.clone()) == x
125 }
126
127 #[quickcheck]
128 fn monoid_right_identity(a: String) -> bool {
129 let x = Dual(a);
130 append(x.clone(), empty::<Dual<String>>()) == x
131 }
132}