I just created a small library for this:
https://github.com/anfelor/elm-units
It allows for time to be used like this:
Units.Time.every (30 ::: milliseconds) Tick
Am Donnerstag, 28. Juli 2016 20:42:44 UTC+2 schrieb John Bugner:
>
> In the time library (
> package.elm-lang.org/packages/elm-lang/core/4.0.3/Time ), there are many
> functions under the "Units" heading. Under the function `millisecond`, it
> says:
> >Units of time, making it easier to specify things like a half-second (500
> * millisecond) without remembering Elm’s underlying units of time.
> I find this underwhelming, because nothing forces me to use these unit
> functions. I could write `every 5 toMsg` and the compiler will not stop me.
> How long of a time am I actually specifying? Probably 5 milliseconds,
> because I infer that it's probably using the same unit as JavaScript, but I
> can't know for sure. A beginner might think 5 seconds, because it's the
> unit that has no prefixes, or 5 minutes if 5 minutes seems appropriate to
> what the application does. This is very bad; There should never be doubt
> about what unit is being used, and the compiler should enforce this unit
> correctness. Currently, Elm can't do this, because `Time` is just an alias
> for `Float`.
>
> To prevent this kind of error, I propose a new language construct that I
> call a "unit type". It would have the following properties:
> (1) A definition that would look (very roughly) like this:
> ```
> type unit Time as Float
> = Second
> | Millisecond == Second 0.0001
> | Nanosecond == Millisecond 0.0001
> | Minute == Second 60
> | Hour == Minute 60
> | Day == Hour 24
> | Year == Day 365
> ```
>
> The point of the definition is to:
> (a) Provide an easy way to define different units that measure the same
> thing (in this case, time, but you could do the same thing for
> length/height/depth in either metric or US imperial units) as constructors.
> (b) Tell how they are related to eachother. (A minute is 60 seconds, an
> hour is 60 minutes, etc.) The compiler would check that all relations of
> the constructors eventually flow to a single base unit (in this case,
> `Second`). A cycle would be disallowed.
> (c) Tell what type the unit is based on (in this case, `Float`). (Perhaps
> non-number types would be disallowed.)
>
> (2) Given that `every` still has the same signature: `Time -> (Time ->
> msg) -> Sub msg`, `every 5 toMsg` would cause a compile-time error, because
> the types don't match; The function expects a number with a `Time` unit,
> but receives `5`, which is just a raw number (a number without any unit).
> (3) When writing a function that has a parameter of type `Time`, pattern
> matching only matches the base unit constructor, not every constructor like
> a normal (data/enum) type. The compiler would automatically convert the
> other units to the base unit with the conversions that the programmer
> provided in the definition.
> (4) Comparison, addition, and subtraction would be automatically
> implemented for the type, so two times of any combination of constructors
> could be compared, added, or subtracted with ease. `(Minute 5) - (Second
> 20) == (Millisecond 280000)` would "just work". "Time + Float" (or "Time +
> Length") would cause a compile-time error.
> (5) Perhaps compound unit types like "Time^2" would be supported, so a
> "Time * Time" would yield "Time^2", "Time * Float" would yield "Time", and
> "Time * Length" would yield just that: "Time * Length". ("Force" would be
> an alias of "Mass * Length / (Second^2)".)
>
> I know that this is a very radical proposal, (I don't know of any language
> that has a feature like this.) but I bring it up anyways, because although
> it's been 18 years since the mars probe crashed because of a unit error
> (one module assumed that the number it was getting was in metric units, and
> another assumed that it was getting it in US imperial units) (
> https://en.wikipedia.org/wiki/Mars_Climate_Orbiter ), I'm amazed that
> since then, programming languages have done nothing to prevent this kind of
> error from happening again, besides just admonishing programmers to be
> careful. (As if the NASA programmers at the time weren't already trying to!)
>
> Letting `5` be a legal unitless `Time` value is just as silly and
> dangerous as letting `bool a = 2;` be a legal statement in C. data/enum
> types prevent this from happening to `Bool` in Elm, and unit types could
> prevent the same kind of thing from happening to `Time`.
>
> Questions, comments, related thoughts, etc are welcome.
>
>
--
You received this message because you are subscribed to the Google Groups "Elm
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.