
On Mon, Dec 6, 2010 at 7:01 PM, Paul Higham
Yes, I believe that the point of the exercise was only to grok the semantics and applicability of foldr, it is a rather unnatural way to express init.
This is a fairly simple solution: init' :: [a] -> [a] init' ls = foldr (\x xs n -> if n == 0 then [] else x : xs (n - 1)) (const []) ls (length ls - 1) Of course, *init'* will fail on infinite lists. Tail can be defined using * foldr* too, though: tail' :: [a] -> [a] tail' ls = foldr (x xs (y:ys) -> ys) id ls ls *takeWhile* and *dropWhile* can be defined similarly, as well as other folds that "depend" on a value, or require the fold to terminate before the entire list has been processed. Anyways, they seem like fairly natural solutions to the problem.