无法从算术序列中推断出枚举a

时间:2018-01-17 14:11:11

标签: list haskell enums

我是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)

感谢您的帮助。

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>结构,因此它导出0genericLength x-1应该具有类型[a],但它不知道如何枚举它。然而,所有上述推理都是基于传递给foldr的错误论据。

我也认为我们根本不需要genericLength。我猜我可以使用lengthInt,所以:

--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

这是(给你计算行列式)正确的答案。