Creating an instance of the Fractional Typeclass in Haskell

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-10 05:23:29

问题


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


回答1:


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.



来源:https://stackoverflow.com/questions/27314929/creating-an-instance-of-the-fractional-typeclass-in-haskell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!