elm-units icon indicating copy to clipboard operation
elm-units copied to clipboard

Add support for non-negative units

Open DavidDTA opened this issue 1 year ago • 1 comments

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.

DavidDTA avatar Jul 18 '22 20:07 DavidDTA

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.)

ianmackenzie avatar Jul 19 '22 17:07 ianmackenzie