goldfirere / units

The home of the units Haskell package
94 stars 19 forks source link

Confusing type error because of bad fixity declaration #41

Closed hesiod closed 9 years ago

hesiod commented 9 years ago

Consider a data type like this:

data Object lcsu vec = Object { m :: Mass lcsu (Scalar vec), v :: Velocity lcsu vec }

It is defined independently of the number of dimensions of its vectors.

Now, say you want to construct an Object like this (expanded to show the type annotations):

ve :: Velocity SI (Double, Double)
ve = (1, 1) % Meter :/ Second
ma :: Mass SI Double
ma = 1 % Gram
object = Object ma ve

The compiler will complain to you that (shortened):

    Couldn't match type ‘Qu
                           '['F Data.Dimensions.SI.Length One] lcsu0 (t0, t1)
                         :/ Second’
                  with ‘Qu
                          (DimFactorsOf Data.Dimensions.SI.Velocity)
                          (MkLCSU
                             '[(Data.Dimensions.SI.Length, Meter),
                               (Data.Dimensions.SI.Mass, Kilo :@ Gram),
                               (Data.Dimensions.SI.Time, Second),
                               (Data.Dimensions.SI.Current, Ampere),
                               (Data.Dimensions.SI.Temperature, Kelvin),
                               (Data.Dimensions.SI.AmountOfSubstance, Mole),
                               (Data.Dimensions.SI.LuminousIntensity, Lumen)])
                          (Double, Double)’
    Expected type: Velocity SI (Double, Double)
      Actual type: Qu
                     '['F Data.Dimensions.SI.Length One] lcsu0 (t0, t1)
                   :/ Second
    In the expression: (1, 1) % Meter :/ Second
    In an equation for ‘ve’: ve = (1, 1) % Meter :/ Second

The example solves this by creating the Vec2D type family, but I'm wondering if there is any way to solve this without giving up the dimension polymorphism mentioned above.

goldfirere commented 9 years ago

This is a simple one: you're just missing parentheses. :)

ve = (1, 1) % (Meter :/ Second)

However, I'm leaving this ticket open as a reminder to re-examine fixity declarations, as I think I've gotten them wrong.

hesiod commented 9 years ago

Such a trivial mistake... thanks anyway.