Parameters in anonymous function

Viewed 197

I've been practicing with anonymous functions and got the following:

takeWhile' :: (a -> Bool) -> [a] -> [a]
takeWhile' f xs = foldl (\x y z -> if (f x) && z then x : y else y) xs [] True

which is basically a rewrite of the takeWhile function already in Haskell.

For those who don't know, the takeWhile function takes a list and a function and returns a new list with every element in the original list that satisfies the function until one of them gives false.

From my point of view everything seems to be correct, I have 3 arguments x y and z ready to use in my anonymous function, x being the list of numbers, y the empty list where I'll be inserting every element and z is basically a debouncer so that if one of the elements doesn't meet the requirements, we don't insert any more.

And yet Haskell gives me the following error:

"Occurs check: cannot construct the infinite type: a ~ Bool -> [a]"

Any idea why?

1 Answers

The fold function in fold takes as parameters the accumulator x, and the element y. So there is no z that is passed.

But even if that was somehow possible, there are still other issues. x is the accumulator here, so a list, that means that x : y makes no sense, since (:) :: a -> [a] -> [a] takes an element and a list, and constructs a new list.

You can however easily make use of foldr to implement a takeWhile function. Indeed:

takeWhile' p = foldr (\x -> if p x then (x :) else const []) []

We here thus check if the predicate holds, if that is the case, we preprend the accumulator with x. If not, we return [], regardless of the value of the accumulator.

Due to the laziness of foldr, it will not look for elements after an element has failed the accumulator, since const [] will ingore the value of the accumulator.

Related