我的矩阵乘法实现是:
mtrxMult :: (Num a) => [[a]] -> [a] -> [a] -> [a]
mtrxMult [[]] _ _ = []
mtrxMult xs [] vec = 0 : mtrxMult xs vec vec
mtrxMult (x:xs) (v:vs) vec = head x * v + mtrxMult (tail x : xs) vs vec
我们的想法是,函数调用mtrxMult [[0,1],[1,0]] [2,3] [2,3]
将扩展为0 * 2 + 1 * 3 : 2 * 1 + 3 * 0 : []
,评估为[3,2]
。但是,编译器希望x是列表列表而不是头部是数字的列表。那么Haskell的类型推理系统给出了它的期望,以及如何改变代码以实现矩阵乘法的连贯实现?
答案 0 :(得分:1)
编译时错误很容易修复,但我认为你可能会遇到更大的问题......
表达式的签名是错误的。我想你试图将NxM矩阵乘以长度为N的向量,即 -
| a b | | x | | ax + by |
| c d | X | y | = | cx + dy |
| e f | | ex + fy |
如果我是正确的,该函数的签名应为
mtrxMult::Num a=>[[a]]->[a]->[a]
并且实现将是
dotMult::Num a=>[a]->[a]->a
dotMult x y | length x == length y = sum $ zipWith (*) x y
dotMult x y = error "Vectors should be of same length in call to dotMult"
mtrxMult::Num a=>[[a]]->[a]->[a]
mtrxMult m x | length x == length m = map (dotMult x) y
mtrxMult _ _ = error "Matrix width must be vector length"
(运行时长度检查打扰了我......你可能通过定义“data Matrix = Matrix [Vector]”来制作一些可以将一些类型检查移动到编译时间的东西,但我只是在这里保留了数组)。