Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Any good idea how to integrate with ordered_float? #75

Open
TonalidadeHidrica opened this issue Sep 25, 2021 · 3 comments
Open

Any good idea how to integrate with ordered_float? #75

TonalidadeHidrica opened this issue Sep 25, 2021 · 3 comments

Comments

@TonalidadeHidrica
Copy link

Sometimes we want to sort a list of physical quantities. For such purpose, ordered_float is useful; we want to handle with Vec<Meter<OrderedFloat<f64>>>. However, useful constants like M and KG are defined only for primitive types, so there seems no really easy way to multiply quantities. Any idea how to deal with such situation? Currently I'm thinking of making a module named ordered_float_f64_consts or something, copying entire contents of f64consts (expanded by cargo-expand) to my project. Maybe it would be useful if this library provides a macro for defining arbitrary-type constants for existing unit system.

Thanks for this amazing project, by the way! I'm enjoying exploring the type-safety world of physical computations.

@paholg
Copy link
Owner

paholg commented Sep 26, 2021

I like the idea of allowing custom types for consts-generation. I'm (slowly) rewriting dimensioned to use proc-macros, so now is probably not the best time to add it.

It doesn't get you all the functionality you want, but you could define a trait to inject OrderedFloat inside a, say, SI type:

use dimensioned::si::{Meter, M, SI};
use ordered_float::OrderedFloat;

pub trait Wrap {
    type Output;

    fn wrap(self) -> Self::Output;
}

impl<U, V> Wrap for SI<V, U> {
    type Output = SI<OrderedFloat<V>, U>;

    fn wrap(self) -> Self::Output {
        SI::new(OrderedFloat(self.value_unsafe))
    }
}

fn main() {
    let mut v: Vec<Meter<OrderedFloat<f64>>> = Vec::new();

    v.push((7.0 * M).wrap());
}

@TonalidadeHidrica
Copy link
Author

Thanks. That's indeed the most sensible way to do that. Another problem is that it is hard to do arithmetic operations between ordered-float-si-values, but maybe we should unwrap them before calculating, and only use the wrapped value when storing into, say, vecs or btreemaps?

@paholg
Copy link
Owner

paholg commented Oct 1, 2021

Another problem is that it is hard to do arithmetic operations between ordered-float-si-values

Is it? What issue have you been having? It seem to work fine for me:

    let x = (7.0 * M).wrap();
    let y = (3.0 * M).wrap();
    println!("{}", x + y);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants