I am new to haskell and trying out some exercises
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
.
I think you wanted to do x:y
?
Recall the type of 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.
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; and the result of applying this lambda should have the same type as y
.
But the type of (:)
is a -> [a] -> [a]
--that is, it appends a single element to the head of a list. 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.
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. 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:
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.