在Haskell中创建Fractional类型类的实例

时间:2014-12-05 11:28:57

标签: haskell instance typeclass

我是一名自学成才的Haskell爱好者,我正在构建一种名为 Physical 的新类型,我可以使用它来表示物理量。它使用两个 Float 分别表示物理量的值及其不确定性。

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

我使用标准规则来计算总和,差异和两个量的乘积的不确定性,以定义 Num 类型类的实例。

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))

到目前为止,我可以毫不费力地使代码工作。但是,当我尝试将物理这样的 Fractional 的实例设为

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

加载我的代码时出现错误,说明我的代码(Main./)中的(/)与Prelude(Prelude。/)导出的(/)之间存在模糊不清的地方,无论我在哪里使用(/)我的代码,特别是在Fractional中的Physical实例的定义中。

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')

这让我很困惑,因为操作符(+)的模糊不存在没有问题,因为我使用它在Num中创建Physical的实例,就像我使用(/)创建一个分数的物理实例。

1 个答案:

答案 0 :(得分:7)

缺少缩进。缩进你的代码。

错误

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

正确

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

解释

您实际上定义了一个新的顶级(/)。您的实际Fractional实例为空。如果不是因为模糊的情况,你会收到没有明确实现的警告。