[英]Haskell error using foldr
I am new to haskell and trying out some exercises 我是Haskell的新手,并尝试了一些练习
I dont understand whats the error generated and why it is generated 我不明白错误产生的原因以及产生原因
split = foldr
(\x y -> y:x)
[[]]
the error on the interpretator is as below 解释器上的错误如下
Occurs check: cannot construct the infinite type: a0 = [a0]
In the first argument of `(:)', namely `y'
In the expression: y : x
In the first argument of `foldr', namely `(\ x y -> y : x)'
Failed, modules loaded: none.
anyone can help? 有人可以帮忙吗? Thanks in advance
提前致谢
Type of foldr is 文件夹类型为
foldr :: (a -> b -> b) -> b -> [a] -> b
so in split 所以在分裂
split = foldr (\x y -> y:x) [[]]
y
and y:x
has to be of same type, which is not possible for any x
and y
as y:x
will always be one step deeper in the list than y
. y
和y:x
必须具有相同的类型,这对于任何x
和y
都是不可能的,因为y:x
在列表中始终比y
更深一步。
I think you wanted to do x:y
? 我想你想做
x:y
吗?
Recall the type of foldr
: (a -> b -> b) -> b -> [a] -> b
. 回忆文件
foldr
的类型: (a -> b -> b) -> b -> [a] -> b
foldr
(a -> b -> b) -> b -> [a] -> b
。 This says that foldr
expects a function that combines an element of the list with a value of the final result type, producing a new value of the result type. 这表示
foldr
需要一个函数,该函数将列表的元素与最终结果类型的值组合在一起,从而产生结果类型的新值。
For the first argument, you've given foldr
the function \\xy -> y:x
, where x
will be the list elements and y
the result of the next step to the right; 对于第一个参数,您给了
foldr
函数\\xy -> y:x
,其中x
是列表元素, y
是下一步的结果; and the result of applying this lambda should have the same type as y
. 并且应用此lambda的结果应与
y
具有相同的类型。
But the type of (:)
is a -> [a] -> [a]
--that is, it appends a single element to the head of a list. 但是
(:)
的类型是a -> [a] -> [a]
-也就是说,它将单个元素附加到列表的开头。 In the expression y:x
, you're taking something of the "result" type and using it as an element of a list used as the result. 在表达式
y:x
,您将采用某种“结果”类型,并将其用作用作结果的列表的元素。
Because of that, GHC attempts to infer that the result type b
is the same as the type [b]
, which is then of course the same as the type [[b]]
, and [[[b]]]
... and so on. 因此,GHC尝试推断结果类型
b
与类型[b]
相同,然后当然与类型[[b]]
和[[[b]]]
...等等。 Thus it complains about an "infinite type". 因此,它抱怨“无限类型”。
The posts before me answer your question, but after your comment i can see that you want a function that splits your list by a predicate. 在我之前的帖子回答了您的问题,但是在您发表评论之后,我可以看到您想要一个按谓词将列表分开的函数。
You can use groupWith::Ord b => (a -> b) -> [a] -> [[a]] from the module GHC.Exts and supply it with a function of type (a -> Bool) in your example: 您可以使用模块GHC.Exts中的groupWith :: Ord b =>(a-> b)-> [a]-> [[a]],并在您的模块中为其提供类型为(a-> Bool)的函数例:
groupWith even [1,2,3,4,5,6] yields [[1,3,5],[2,4,6]]
Also, something ugly but that achieves the type of "outing" you want is: 另外,有些丑陋但可以实现所需的“外出”类型的东西是:
split::Eq a => (a -> Bool) -> [a] -> [[a]]
split f ls = (ls \\ rl):rl:[]
where rl = filter f ls
But this will always split the supplied list in just two lists because of the binary function you supply. 但是,由于您提供的二进制函数,总是会将提供的列表分成两个列表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.