编译错误:发生检查:无法构造无限类型:a1 = [a1]

时间:2013-11-17 04:55:43

标签: haskell

我有一个功能:

changeIn2dList :: (Eq a) => (Int, Int) -> a -> [[a]] -> [[a]] 
changeIn2dList _ _ [] = error "Can't change empty list" 
changeIn2dList (x, y) w (z:zs) 
  | x == 0 = changeInList y w z 
  | otherwise = z:(changeIn2dList (x-1, y) w zs)

当我编译它时,我收到此错误:

Could not deduce (a ~ [a])
 from the context (Eq a)
   bound by the type signature for
              changeIn2dList :: Eq a => (Int, Int) -> a -> [[a]] -> [[a]]
   at starter/Helpers.hs:25:19-61
   `a' is a rigid type variable bound by
       the type signature for
          changeIn2dList :: Eq a => (Int, Int) -> a -> [[a]] -> [[a]]
       at starter/Helpers.hs:25:19
 In the second argument of `changeInList', namely `w'
 In the expression: changeInList y w z
 In an equation for `changeIn2dList':
     changeIn2dList (x, y) w (z : zs)
       | x == 0 = changeInList y w z
       | otherwise = z : (changeIn2dList (x - 1, y) w zs)

如果我从函数中删除了类型定义:

--changeIn2dList :: (Eq a) => (Int, Int) -> a -> [[a]] -> [[a]] 
changeIn2dList _ _ [] = error "Can't change empty list" 
changeIn2dList (x, y) w (z:zs) 
| x == 0 = changeInList y w z 
| otherwise = z:(changeIn2dList (x-1, y) w zs)

错误更改:

Occurs check: cannot construct the infinite type: a1 = [a1]
In the first argument of `(:)', namely `z'
In the expression: z : (changeIn2dList (x - 1, y) w zs)
In an equation for `changeIn2dList':
    changeIn2dList (x, y) w (z : zs)
      | x == 0 = changeInList y w z
      | otherwise = z : (changeIn2dList (x - 1, y) w zs)

看起来问题在于行

| otherwise = z : (changeIn2dList (x - 1, y) w zs)

它不喜欢z:([[a]])操作。 z不是列表而(changeIn2dList (x - 1, y) w zs)不是2D列表吗?为什么会有问题?


我的changeInList功能(有效)

changeInList :: (Eq a) => Int -> a -> [a] -> [a]
changeInList _ _ [] = error "Can't change empty list"
changeInList x w (z:zs)
  | x == 0 = w:zs
  | otherwise = z:(changeInList (x - 1) w zs)

1 个答案:

答案 0 :(得分:2)

这是代码中的一个非常小的错误,我想一旦你看到它,你就会意识到为什么编译器会给你错误。对于x == 0changeIn2dList的情况,您只需要调用changeInList,而不会将其添加到列表的其余部分。如果将其更改为changeInList y w z : zs,它将按预期编译并运行。

之所以这样,是因为您告诉编译器changeIn2dList返回类型[[a]],但您返回changeInList的值,[a]类型为[[a]] ,所以它试图将[a]a ~ [a]等同,这必须代表{{1}}。

当您删除类型签名时,它会从第一个案例中派生出类型,并在第二个案例中看到问题。