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

Add support for non-negative units #60

Open
DavidDTA opened this issue Jul 18, 2022 · 1 comment
Open

Add support for non-negative units #60

DavidDTA opened this issue Jul 18, 2022 · 1 comment

Comments

@DavidDTA
Copy link

DavidDTA commented Jul 18, 2022

The Quantity API allows for the wrapped value to be any numeric value. In some cases, units that are less than zero are not possible, and it would be nice to make impossible states impossible in those cases.

One way to accomplish this would be to introduce a new type (e.g. AbsoluteQuantity) which enforces that its value is always non-negative via its API.

My specific use case involves measuring periods of time, and

type alias TimeBlock = { start: Time.Posix, duration = Duration.Duration }

allows for impossible states when the duration is negative, but

type alias TimeBlock = { start: Time.Posix, duration = <non-negative duration type here> }

does not.

@ianmackenzie
Copy link
Owner

I think a new type like NonNegativeQuantity would be tricky, since then you'd presumably need NonNegativeDuration, NonNegativeLength etc. types/modules, with a bunch of duplicate logic to create a new NonNegativeDuration from a non-negative value in seconds, minutes, hours etc. - it would basically be a full separate copy of the elm-units API.

One possibility might be to (ab)use the first type parameter of Quantity to use an underlying non-negative numeric type (e.g. a hypothetical NonNegativeFloat type, published as an independent package). By itself that wouldn't be super useful since you wouldn't be able to use any of the functions in (e.g.) the Duration module, but if we added something like

Quantity.map : (a -> b) -> Quantity a units -> Quantity b units

then you could do something like Quantity.map NonNegativeFloat.toFloat myNonNegativeQuantity to get a 'normal' quantity that you could do math with. (I'd be open to adding map, map2 etc. functions - they're a little unsafe since they would provide a pretty easy way to subvert units safety, but I can see them being pretty useful in some cases.)

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