在Haskell中更改不需要的类型推断

时间:2013-12-14 03:53:38

标签: haskell

我的矩阵乘法实现是:

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的类型推理系统给出了它的期望,以及如何改变代码以实现矩阵乘法的连贯实现?

1 个答案:

答案 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]”来制作一些可以将一些类型检查移动到编译时间的东西,但我只是在这里保留了数组)。