1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//! Types that extend [`Semiring`](crate::classes::Semiring) with subtraction.
//!
//! ### Examples
//!
//! ```
//! use fp_library::classes::Ring;
//!
//! assert_eq!(i32::subtract(5, 3), 2);
//! ```
#[fp_macros::document_module]
mod inner {
use {
crate::classes::*,
fp_macros::*,
};
/// A type class for types that extend [`Semiring`] with subtraction.
///
/// ### Laws
///
/// * Additive inverse: `subtract(a, a) = zero`
/// * Compatibility: `subtract(a, b) = add(a, negate(b))`
#[document_examples]
///
/// ```
/// use fp_library::classes::{
/// Ring,
/// Semiring,
/// };
///
/// // Additive inverse: subtract(a, a) = zero
/// assert_eq!(i32::subtract(5, 5), i32::zero());
/// ```
pub trait Ring: Semiring {
/// Subtracts the second value from the first.
#[document_signature]
///
#[document_parameters("The value to subtract from.", "The value to subtract.")]
///
#[document_returns("The difference.")]
#[document_examples]
///
/// ```
/// use fp_library::classes::Ring;
///
/// assert_eq!(i32::subtract(5, 3), 2);
/// ```
fn subtract(
a: Self,
b: Self,
) -> Self;
}
/// Subtracts the second value from the first.
///
/// Free function version that dispatches to [`Ring::subtract`].
#[document_signature]
///
#[document_type_parameters("The ring type.")]
///
#[document_parameters("The value to subtract from.", "The value to subtract.")]
///
#[document_returns("The difference.")]
#[document_examples]
///
/// ```
/// use fp_library::classes::ring::subtract;
///
/// assert_eq!(subtract(5i32, 3), 2);
/// ```
pub fn subtract<R: Ring>(
a: R,
b: R,
) -> R {
R::subtract(a, b)
}
/// Negates a value (additive inverse).
///
/// Equivalent to `subtract(zero, a)`.
#[document_signature]
///
#[document_type_parameters("The ring type.")]
///
#[document_parameters("The value to negate.")]
///
#[document_returns("The negated value.")]
#[document_examples]
///
/// ```
/// use fp_library::classes::ring::negate;
///
/// assert_eq!(negate(5i32), -5);
/// ```
pub fn negate<R: Ring>(a: R) -> R {
R::subtract(R::zero(), a)
}
macro_rules! impl_ring_int {
($($t:ty),+) => {
$(
impl Ring for $t {
/// Subtracts using wrapping subtraction.
#[document_signature]
///
#[document_parameters("The value to subtract from.", "The value to subtract.")]
///
#[document_returns("The difference (wrapping on overflow).")]
#[document_examples]
///
/// ```
#[doc = concat!("use fp_library::classes::Ring;")]
///
#[doc = concat!("assert_eq!(<", stringify!($t), ">::subtract(5 as ", stringify!($t), ", 3 as ", stringify!($t), "), 2 as ", stringify!($t), ");")]
/// ```
fn subtract(a: Self, b: Self) -> Self { a.wrapping_sub(b) }
}
)+
};
}
impl_ring_int!(i8, i16, i32, i64, i128, isize);
macro_rules! impl_ring_float {
($($t:ty),+) => {
$(
impl Ring for $t {
/// Subtracts using the `-` operator.
#[document_signature]
///
#[document_parameters("The value to subtract from.", "The value to subtract.")]
///
#[document_returns("The difference.")]
#[document_examples]
///
/// ```
#[doc = concat!("use fp_library::classes::Ring;")]
///
#[doc = concat!("assert_eq!(<", stringify!($t), ">::subtract(5.0 as ", stringify!($t), ", 3.0 as ", stringify!($t), "), 2.0 as ", stringify!($t), ");")]
/// ```
fn subtract(a: Self, b: Self) -> Self { a - b }
}
)+
};
}
impl_ring_float!(f32, f64);
}
pub use inner::*;