我有一个功能:
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)
答案 0 :(得分:2)
这是代码中的一个非常小的错误,我想一旦你看到它,你就会意识到为什么编译器会给你错误。对于x == 0
中changeIn2dList
的情况,您只需要调用changeInList
,而不会将其添加到列表的其余部分。如果将其更改为changeInList y w z : zs
,它将按预期编译并运行。
之所以这样,是因为您告诉编译器changeIn2dList
返回类型[[a]]
,但您返回changeInList
的值,[a]
类型为[[a]]
,所以它试图将[a]
与a ~ [a]
等同,这必须代表{{1}}。
当您删除类型签名时,它会从第一个案例中派生出类型,并在第二个案例中看到问题。