简体   繁体   中英

Creating an instance of the Fractional Typeclass in Haskell

I am a self-taught Haskell enthusiast and I was building a new type called Physical which I could use to represent physical quantities. It uses two Float s representing the value of the physical quantity and its uncertainty respectively.

data Physical = Physical {
    value :: Float,
    err :: Float
}

I used standard rules for the uncertainty of a sum, difference and a product of two quantities to define an instance of the Num typeclass.

instance Num Physical where
    (Physical v1 u1) + (Physical v2 u2) = (Physical (v1+v2) (u1+u2))
    (Physical v1 u1) - (Physical v2 u2) = (Physical (v1-v2) (u1+u2))
    (Physical v1 u1) * (Physical v2 u2) = (Physical (v1*v2) (sqrt((u1 /v1)^2 + (u2 /v2)^2)*v1*v2))

I had no trouble getting the code to work so far. However, when i tried to make Physical an instance of Fractional like this

instance Fractional Physical where
(Physical v1 u1) / (Physical v2 u2) = (Physical (v1 / v2) (sqrt((u1 /v1)^2 + (u2 /v2)^2)*(v1 /v2)))

I get an error upon loading my code stating that there is an ambiguous occurrence between the (/) in my code (Main./) and (/) exported by Prelude (Prelude./) wherever i use (/) in my code, especially inside the definition of the instance of Physical in Fractional.

Physical.hs:23:19:
    Ambiguous occurrence `/'
    It could refer to either `Main./', defined at Physical.hs:15:18
                          or `Prelude./',
                             imported from `Prelude' at Physical.hs:1:1
                             (and originally defined in `GHC.Real')

This confuses me a great deal, since there is no problem with an ambiguous occurrence of the operator (+) as I am using it to make an instance of Physical in Num the same way I am using (/) to create an instance of Physical in Fractional.

Missing indentation. Indent your code.

Wrong

instance Fractional Physical where
(Physical v1 u1) / (Physical v2 u2) = (Physical (v1 / v2) (sqrt((u1 /v1)^2 + (u2 /v2)^2)*(v1 /v2)))

Correct

instance Fractional Physical where
  (Physical v1 u1) / (Physical v2 u2) = (Physical (v1 / v2) (sqrt((u1 /v1)^2 + (u2 /v2)^2)*(v1 /v2)))

-- even a single space would be ok

Explanation

You actually define a new top level (/) . Your actual Fractional instance is empty. If it wasn't for the ambiguous occurrences, you would get warnings for no explicit implementations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM