gpt4 book ai didi

定义向量时出现 Haskell 歧义 (+)

转载 作者:行者123 更新时间:2023-12-02 10:17:58 28 4
gpt4 key购买 nike

我想定义一个带有 x, y, z 坐标的 3D 矢量。可以使用(+)运算符添加向量,并可以使用length函数计算长度

如果我想编译它,我会收到以下错误:

It could refer to either `Prelude.+',
imported from `Prelude' at hello.hs:1:1
(and originally defined in `GHC.Num')
or `Main.+', defined at hello.hs:9:14

代码是:

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

(+) :: Vec3 -> Vec3 -> Vec3
(Vec3 a b c) + (Vec3 t u w) = Vec3 (a+t) (b+u) (c+w)

length :: Vec3 -> Float
length (Vec3 a b c) = sqrt( a*a + b*b + c*c )

vv = Vec3 1.5 0.7 2.2

main :: IO ()
main = do
print $ length vv

最佳答案

要真正重载 + 运算符,您需要定义一个 Num 实例,例如

instance Num Vec3 where
Vec3 a b c + Vec3 t u w = Vec3 (a+t) (b+u) (c+w)
Vec3 a b c * Vec3 t u w = ...

这实际上就是linearhmatrix库对其向量类型进行了处理,(基本上)也是非常流行的 NumPy 。 Python 框架。

我强烈建议反对这一点,因为向量空间的语义在某种意义上与普通标量的语义不兼容。特别是,您需要在这里定义乘法;正确处理这些类型签名的唯一方法是组件方式,就像 Matlab 的 .* 运算符

  Vec3 a b c * Vec3 t u w = Vec3 (a*t) (b*u) (c*w)

但这对于向量本身没有数学意义,仅对于向量在特定基础上的扩展有意义。此外,如果您错误地将向量定义为单个数字(在线性中将数字粘贴到所有向量分量中,呃!),它也很容易导致错误。

更适合的是 Monoid 类,如 suggested by Reaktormonk 。但是,您可能会发现自己也需要缩放操作

(*^) :: Float -> Vec3 -> Vec3
μ *^ Vec3 t u w = Vec3 (μ*t) (μ*u) (μ*w)

(与分量乘法不同, this is defined for any vector space ),而 Monoid 不提供此功能。

此类类型的正确类是 VectorSpace .

instance AdditiveGroup Vec3 where
Vec3 a b c ^+^ Vec3 t u w = Vec3 (a+t) (b+u) (c+w)
negateV v = (-1)*^v
instance VectorSpace Vec3 where
type Scalar Vec3 = Float
μ *^ Vec3 t u w = Vec3 (μ*t) (μ*u) (μ*w)

关于定义向量时出现 Haskell 歧义 (+),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42873296/

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