Hi, I have a partial function like:
fn foo<T1, T2>(x: T1, y: T2) -> Option<T2> where...
I've seen that I could make it total restricting the input like this:
fn foo<T1, T2>(x: T1, y: NonZero<T2>) -> T2 where...
Turning/writing functions into total ones is an excellent thing to do, in general. Good modern languages need to do all they can to help this!
But the stdlib has NonZeroXXX
instead of NonZero<>
(for reasons I don't know). Do you have ideas?
1 Like
alice
2
What sort of operations do you need to perform on the generic types?
Reminder/division (but how is that important for the topic?)
alice
4
One option would be something like this:
trait HasNonZero {
type NonZero;
fn from_nonzero(v: Self::NonZero) -> Self;
}
impl HasNonZero for u8 {
type NonZero = std::num::NonZeroU8;
fn from_nonzero(v: Self::NonZero) -> Self {
v.get()
}
}
impl HasNonZero for u16 {
type NonZero = std::num::NonZeroU16;
fn from_nonzero(v: Self::NonZero) -> Self {
v.get()
}
}
impl HasNonZero for u32 {
type NonZero = std::num::NonZeroU32;
fn from_nonzero(v: Self::NonZero) -> Self {
v.get()
}
}
You can now do:
fn foo<T1, T2>(x: T1, y: T2::NonZero) -> T2
where
T2: HasNonZero,
T1: Div<T2::NonZero, Output = T2>,
{
x / y
}
or alternatively
fn foo<T1, T2>(x: T1, y: T2::NonZero) -> T2
where
T2: HasNonZero,
T1: Div<T2, Output = T2>,
{
x / T2::from_nonzero(y)
}
1 Like
system
Closed
5
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.