ianmackenzie / elm-units

Simple, safe and convenient unit types and conversions for Elm
https://package.elm-lang.org/packages/ianmackenzie/elm-units/latest/
BSD 3-Clause "New" or "Revised" License
85 stars 14 forks source link

Add minutes/seconds support to Angle #21

Closed ianmackenzie closed 5 years ago

ianmackenzie commented 6 years ago

At a minimum:

Angle.minutes : Float -> Angle
Angle.inMinutes : Angle -> Float
Angle.seconds : Float -> Angle
Angle.inSeconds : Angle -> Float

Perhaps also some support for compound definitions, something like:

Angle.fromRecord : { degrees : Float, minutes : Float, seconds : Float } -> Angle
Angle.toRecord : Angle -> { degrees : Float, minutes : Float, seconds : Float }

Or perhaps:

Angle.degreesMinutesSeconds : ( Float, Float, Float ) -> Angle
Angle.inDegreesMinutesSeconds : Angle -> ( Float, Float, Float )

For the compound definitions, how exactly should negative angles be converted to degrees/minutes/seconds?

ianmackenzie commented 5 years ago

Brainstorming a bit, not fully formed:

module Angle exposing
    ( DegreesMinutesSeconds(..)
    , fromDegreesMinutesSeconds
    , toDegreesMinutesSeconds
    )

type DegreesMinutesSeconds
    = Positive { degrees : Float, minutes : Float, seconds : Float }
    | Negative { degrees : Float, minutes : Float, seconds : Float }

fromDegreesMinutesSeconds : DegreesMinutesSeconds -> Angle

toDegreesMinutesSeconds : Angle -> DegreesMinutesSeconds

which you would then use as

angle =
    Angle.fromDegreesMinutesSeconds <|
        Angle.Positive { degrees = 12, minutes = 34, seconds = 56 }

something =
    case angle of
        Angle.Positive { degrees, minutes, seconds } ->
            ...

        Angle.Negative { degrees, minutes, seconds } ->
            ...
ianmackenzie commented 5 years ago

A couple more thoughts from musing about this on the bus:

ianmackenzie commented 5 years ago

Another potential API:

type Sign
    = Positive
    | Negative

fromDms : { sign : Sign, degrees : Int, minutes : Int, seconds : Float } -> Angle

toDms : Angle -> { sign : Sign, degrees : Int, minutes : Int, seconds : Float }

which would be used as

angle =
    Angle.fromDms
        { sign = Angle.Positive
        , degrees = 45
        , minutes = 30
        , seconds = 0
        }

{ sign, degrees, minutes, seconds } =
    Angle.toDms angle

Potential drawback: could be easy to destructure as

{ degrees, minutes, seconds} =
    Angle.toDms angle

and forget to check for sign.

ianmackenzie commented 5 years ago

Implemented in 447c3c53cca69e83ab63ccc445b41b407c539a5f.