我试图覆盖+符号,以了解如何定义自己的类型。我是Haskell的新手,似乎无法克服此错误。
这是我简单的新类型:
newtype Matrix x = Matrix x
(+):: (Num a, Num b, Num c) => Matrix [[a]] -> Matrix [[b]] -> Matrix [[c]]
x + y = Matrix zipWith (\ a b -> zipWith (+) a b) x y
当我尝试将其加载到ghci中时,出现错误
linear_algebra.hs:9:42:
Ambiguous occurrence ‘+’
It could refer to either ‘Main.+’, defined at linear_algebra.hs:9:3
or ‘Prelude.+’,
imported from ‘Prelude’ at linear_algebra.hs:1:1
(and originally defined in ‘GHC.Num’)
Failed, modules loaded: none.
用
代替我的最后一行代码x + y = Matrix zipWith (\ a b -> zipWith (Prelude.+) a b) x y
给我错误
Couldn't match expected type ‘([Integer] -> [Integer] -> [Integer])
-> Matrix [[a]] -> Matrix [[b]] -> Matrix [[c]]’
with actual type ‘Matrix
((a0 -> b0 -> c0) -> [a0] -> [b0] -> [c0])’
Relevant bindings include
y :: Matrix [[b]] (bound at linear_algebra.hs:9:5)
x :: Matrix [[a]] (bound at linear_algebra.hs:9:1)
(+) :: Matrix [[a]] -> Matrix [[b]] -> Matrix [[c]]
(bound at linear_algebra.hs:9:1)
The function ‘Matrix’ is applied to four arguments,
but its type ‘((a0 -> b0 -> c0) -> [a0] -> [b0] -> [c0])
-> Matrix ((a0 -> b0 -> c0) -> [a0] -> [b0] -> [c0])’
has only one
In the expression:
Matrix zipWith (\ a b -> zipWith (Prelude.+) a b) x y
In an equation for ‘+’:
x + y = Matrix zipWith (\ a b -> zipWith (Prelude.+) a b) x y
Failed, modules loaded: none.
能否请您帮助我了解错误所在?我真的很感激。谢谢!
答案 0 :(得分:7)
首先,类型
(+) :: (Num a, Num b, Num c) => Matrix [[a]] -> Matrix [[b]] -> Matrix [[c]]
太笼统了。它指出,即使元素类型不同,也可以将任何数字矩阵与任何其他数字矩阵求和,以生成第三个数字类型的矩阵(可能与前两个数字类型不同)。也就是说,特别是可以将浮点矩阵求和为双精度矩阵,以生成整数矩阵。
您要代替
(+) :: Num a => Matrix [[a]] -> Matrix [[a]] -> Matrix [[a]]
我建议将“列表列表”类型移到新类型内
newtype Matrix a = Matrix [[a]]
反映出列表的列表实现了Matrix
的概念。给出类型签名
(+) :: Num a => Matrix a -> Matrix a -> Matrix a
要“覆盖” (+)
:Haskell中没有覆盖/重载。最接近的选项是:
定义模块本地函数(+)
。这将与Prelude.(+)
发生冲突,因此现在需要对每个+
进行限定,以消除歧义。我们无法编写x + y
,但是我们需要x Prelude.+ y
或x MyModuleName.+ y
。
为Num
实现Matrix a
实例。这不是一个好主意,因为矩阵不完全是一个数字,但是我们仍然可以尝试。
instance Num a => Num (Matrix a) where
Matrix xs + Matrix ys = Matrix (zipWith (zipWith (+)) xs ys)
-- other Num operators here
(*) = error "not implemented" -- We can't match dimension
negate (Matrix xs) = Matrix (map (map negate) xs)
abs = error "not implemented"
signum = error "not implemented"
fromInteger = error "not implemented"
这与您的代码非常相似,缺少一些括号。并非所有其他方法都可以完全有意义地实现,因为Num
是用于数字而不是矩阵。
使用其他运算符,例如(^+)
或其他