我是Haskell的新手并遇到了一个错误,我在尝试编译此代码时无法解决(计算行列式的一部分):
--pivotzeile = 1
--pivotspalte 0 based!
genLaplaceMatrix :: (Num a, Enum a, Num b, Ord b) => [[a]] -> b -> [[a]]
genLaplaceMatrix [[]] _ = error "Cannot calculate LaplaceMatrix from [[]]"
genLaplaceMatrix x pivotSpalte
| pivotSpalte < 0 = error "invalid column"
| pivotSpalte > ((genericLength x) -1) = error "invalid column"
| otherwise = foldr (\y acc -> (conVecs y):acc ) [0..((genericLength x)-1)] []
where
leftPart = take pivotSpalte
rightPart lP z = takeRight (leftPart lP) z
conVecs col = concatVectors (leftPart x!!col) (rightPart (leftPart x!!col) (x!!col) )
错误如下:
main.hs:29:76: error:
• Could not deduce (Enum [a])
arising from the arithmetic sequence ‘0 .. ((genericLength x) - 1)’
from the context: (Num a, Enum a, Num b, Ord b)
bound by the type signature for:
genLaplaceMatrix :: (Num a, Enum a, Num b, Ord b) =>
[[a]] -> b -> [[a]]
at main.hs:24:1-72
• In the second argument of ‘foldr’, namely
‘[0 .. ((genericLength x) - 1)]’
In the expression:
foldr
(\ y acc -> (conVecs y) : acc) [0 .. ((genericLength x) - 1)] []
In an equation for ‘genLaplaceMatrix’:
genLaplaceMatrix x pivotSpalte
| pivotSpalte < 0 = error "invalid column"
| pivotSpalte > ((genericLength x) - 1) = error "invalid column"
| otherwise
= foldr
(\ y acc -> (conVecs y) : acc) [0 .. ((genericLength x) - 1)] []
where
leftPart = take pivotSpalte
rightPart lP z = takeRight (leftPart lP) z
conVecs col
= concatVectors
(leftPart x !! col) (rightPart (leftPart x !! col) (x !! col))
main.hs:29:77: error:
• Could not deduce (Num [a]) arising from the literal ‘0’
from the context: (Num a, Enum a, Num b, Ord b)
bound by the type signature for:
genLaplaceMatrix :: (Num a, Enum a, Num b, Ord b) =>
[[a]] -> b -> [[a]]
at main.hs:24:1-72
• In the expression: 0
In the second argument of ‘foldr’, namely
‘[0 .. ((genericLength x) - 1)]’
In the expression:
foldr
(\ y acc -> (conVecs y) : acc) [0 .. ((genericLength x) - 1)] []
起初我没有定义中的Enum a
,做了一些研究,然后尝试以各种方式添加枚举。可悲的是,他们都没有工作。
它告诉我在创建foldr的第一个列表时出现错误。但那里有什么问题?
完整代码可在repl.it
找到更新: 第二个错误:
main.hs:31:23: error:
• Couldn't match expected type ‘Int’ with actual type ‘b’
‘b’ is a rigid type variable bound by
the type signature for:
genLaplaceMatrix :: forall a b.
(Num a, Enum a, Num b, Ord b) =>
[[a]] -> b -> [[a]]
at main.hs:24:21
• In the first argument of ‘take’, namely ‘pivotSpalte’
In the expression: take pivotSpalte
In an equation for ‘leftPart’: leftPart = take pivotSpalte
• Relevant bindings include
pivotSpalte :: b (bound at main.hs:26:20)
genLaplaceMatrix :: [[a]] -> b -> [[a]] (bound at main.hs:25:1)
感谢您的帮助。
答案 0 :(得分:2)
您可能想要交换foldr
调用的参数,所以:
foldr (\y acc -> (conVecs y):acc ) [0..((genericLength x)-1)] []
为:
foldr (\y -> (conVecs y:)) [] [0..genericLength x-1]
(一些额外的修改)
您收到错误的原因是因为foldr
的结果是[[a]]
。因此,Haskell认为[0..genericLength x-1]
也应该具有类型[[a]]
。由于内部它具有<expr>..<expr>
结构,因此它导出0
和genericLength x-1
应该具有类型[a]
,但它不知道如何枚举它。然而,所有上述推理都是基于传递给foldr
的错误论据。
我也认为我们根本不需要genericLength
。我猜我可以使用length
和Int
,所以:
--pivotzeile = 1
--pivotspalte 0 based!
genLaplaceMatrix :: (Num a, Enum a) => [[a]] -> Int -> [[a]]
genLaplaceMatrix [[]] _ = error "Cannot calculate LaplaceMatrix from [[]]"
genLaplaceMatrix x pivotSpalte
| pivotSpalte < 0 = error "invalid column"
| pivotSpalte > ((genericLength x) -1) = error "invalid column"
| otherwise = foldr (\y -> (conVecs y:)) [] [0..length x-1]
where
leftPart = take pivotSpalte
rightPart lP z = takeRight (leftPart lP) z
conVecs col = concatVectors (leftPart x!!col) (rightPart (leftPart x!!col) (x!!col) )
然后我们获得:
> print $ det [[1,2],[3,4]]
-2
这是(给你计算行列式)正确的答案。