foldr (\x ante->[x]:[ante]) [4] [1,2,3]
因此,如果我得到正确的折叠,第一次函数(\x ante->[x]:[ante])
将执行某些操作,我将调用此函数f,它将在:
f 3 [4] = [3]:[[4]] = [[3],[4]]
为什么这个功能没有这样做?它显示此错误:
* Occurs check: cannot construct the infinite type: a ~ [a]
Expected type: [a]
Actual type: [[a]]
* In the expression: [x] : [ante]
In the first argument of `foldr', namely
`(\ x ante -> [x] : [ante])'
In the expression: foldr (\ x ante -> [x] : [ante]) [4] [1, 2, 3]
* Relevant bindings include
ante :: [a] (bound at testefoldr.hs:51:21)
x :: a (bound at testefoldr.hs:51:19)
folder4 :: [a] (bound at testefoldr.hs:51:1)
|51 | folder4 = foldr (\x ante->[x]:[ante]) [4] [1,2,3]
我创建了一个.hs
然后我放了
folder4 = foldr (\x ante->[x]:[ante]) [4] [1,2,3]
更快的测试。这就是错误中存在folder4的原因。
答案 0 :(得分:4)
foldr
函数的类型为:
foldr :: (a -> b -> b) -> b -> [a] -> b
这意味着它将列表的元素(类型a
)作为输入与累加器(类型b
)一起折叠,并返回一个累加器(再次输入{{1 }})。如果Haskell没有静态类型,它每次都会将累加器包装在一个新列表中。所以它会导致:
b
没有任何意义。
这里有两个问题:
[4]
-> [[3],[4]]
-> [[2],[[3],[4]]]
-> [[1],[[2],[[3],[4]]]]
的类型为ante
,则b
的类型为[x] : [ante]
;和[b]
的类型不是折叠器的结果。所以你可以通过写:
来解决这个问题[4]
答案 1 :(得分:3)
让我们假装这种类型检查,并运行它
foldr (\x ante->[x]:[ante]) [4] [1,2,3]
让我们为f
撰写\x ante -> [x]:[ante]
。
foldr f [4] [1,2,3]
=
f 1 (f 2 (f 3 [4]))
=
f 1 (f 2 ([3]:[[4]]))
=
f 1 (f 2 [[3],[4]])
到目前为止,非常好。
=
f 1 ([2] : [[[3],[4]]])
=
f 1 [[2] , [[3],[4]] ]
现在我们遇到了麻烦。那是[[Int]]
还是[[[Int]]]
?
如果我们继续下去,事情会变得更糟。
问题是f
必须返回与第二个参数类型相同的值。否则,我们无法以f
的方式撰写foldr
。您的f
不会这样做,而是在每次通话时为该类型添加[]
。