Skip to content

Wrapper types? #63

@Rudxain

Description

@Rudxain

Taking inspiration from NonZero<T> and Type-driven parsing, what if this crate (or a separate one, for organizing) provided wrappers for specific numeric properties?

Strawman examples (not tested as compilable):

#[derive(Deref)]
struct Even<T: Integer>(T);

impl<T: Integer> even for Even{
    fn new(x: T) -> Option<Self> {
        if x.is_even() {Some(Self(x))} else {None}
    }
}
// assume `Odd` is defined similarly...

impl<T> Add for Even<T> {
    // even + even = even
    fn add(self, &Self) -> Self
    // even + odd = odd
    fn add(self, &Odd) -> Odd
}
// etc... assume Odd also has similar methods which follow the theorems of math

New fns could be defined that take advantage of such types. If a fn requires a Prime to work properly and safely, it'll no longer have to check primality by itself!

The compiler could optimize code using Even or Odd to have the same size and alignment as Option<Even | Odd> (because LSB is unused).

Existing fns could use these types to guarantee stuff such as

fn sqrt(n: Square<u64>) -> u32

// this equality will be satisfied for all `Square`s!
assert_eq!(sqrt(Square::new(4).unwrap()).pow(2), 4)

If num provided such types, there would be less crates implementing their own wrappers, or worse, doing redundant expensive checks:

use crate1::Prime1;
use crate2::Prime2;
use crate3::CheckedPrime;

crate1::some_fn(Prime1::new(5).unwrap())
crate2::another_fn(Prime2::new(5).unwrap())
crate3::some_fn(CheckedPrime::build(5).unwrap())

If there was 1:

use num_integer::Prime;

let p = Prime::new(5).unwrap();

// assuming all crates have chosen `num` as standard
crate1::new_fn(p)
crate2::yet_another_fn(p)
crate3::foobar_fn(p)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions