gpt4 book ai didi

haskell - 为什么 sum 需要 GHC.Num.fromInteger?

转载 作者:行者123 更新时间:2023-12-02 11:03:21 25 4
gpt4 key购买 nike

我有一个 3d 矢量数据类型,定义为 3 个 float 。我知道,如果我为我的类提供一个 Num 实例并定义普通的数学运算符,我就可以在我的类中使用它们。

data Vec3 = Vec3 { x :: Float
, y :: Float
, z :: Float
} deriving (Show, Eq)

instance Num Vec3 where
(+) v1 v2 = Vec3 (x v1 + x v2) (y v1 + y v2) (z v1 + z v2)

当我将文件加载到 ghci 时,我收到警告,因为我没有定义 Num 中的所有函数,这是有道理的。

Prelude> :l temp.hs
[1 of 1] Compiling Main ( temp.hs, interpreted )

temp.hs:6:10: Warning:
No explicit method or default declaration for `*'
In the instance declaration for `Num Vec3'

temp.hs:6:10: Warning:
No explicit method or default declaration for `abs'
In the instance declaration for `Num Vec3'

temp.hs:6:10: Warning:
No explicit method or default declaration for `signum'
In the instance declaration for `Num Vec3'

temp.hs:6:10: Warning:
No explicit method or default declaration for `fromInteger'
In the instance declaration for `Num Vec3'
Ok, modules loaded: Main.

但是,我仍然可以使用我定义的那些。

*Main> let a = Vec3 1.0 2.0 3.0
*Main> let b = Vec3 2.0 4.0 5.0
*Main> a + b
Vec3 {x = 3.0, y = 6.0, z = 8.0}

我的困惑来自于尝试使用 sum 函数时出现的以下错误

*Main> sum [a,b]
Vec3 {x = *** Exception: temp.hs:6:10-17: No instance nor default method for class operation GHC.Num.fromInteger

为什么 sum 需要为我的 Vec3 数据类型定义一个 fromInteger ?一方面,我认为 sum 仅使用 + 函数,另一方面,我的数据类型不使用 Integer

最佳答案

这是 sum 的实现方式:

sum = foldl (+) 0

注意 0 文字。让我们检查一下它在 GHCi 中的类型:

λ> :t 0
0 :: Num a => a

事实证明,数字文字是 fromInteger 的糖。即,0 实际上是 fromInteger 0

因此,sum 需要 fromInteger,因为上面的定义是糖:

sum = foldl (+) (fromInteger 0)
<小时/>

fromInteger 的实现很简单:

instance Num Vec3 where
fromInteger n = let a = (fromInteger n) in Vec3 a a a

此外,我强烈建议,每当创建实例时,始终对其进行完整定义,以避免出现此类不可预见的麻烦。

关于haskell - 为什么 sum 需要 GHC.Num.fromInteger?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31373070/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com