
Not sure if this thread is still active but I also struggled with this same exercise. I offer the following solution as a thing to shoot at: myInit :: [a] -> [a] myInit ys = foldr snoc [] $ (\(x:xs) -> xs) $ foldr snoc [] ys where snoc = (\x xs -> xs ++ [x]) Note that snoc is defined at the top of the same page as the exercise in Simon's book. ::paul

On Saturday 04 December 2010 23:20:51, Paul Higham wrote:
Not sure if this thread is still active but I also struggled with this same exercise. I offer the following solution as a thing to shoot at:
myInit :: [a] -> [a] myInit ys = foldr snoc [] $ (\(x:xs) -> xs) $ foldr snoc [] ys where snoc = (\x xs -> xs ++ [x])
init === reverse . tail . reverse only holds for finite lists, for infinite lists xs, reverse xs = _|_, but init xs = xs. Also, it's inefficient, but that's not the point of the exercise.
Note that snoc is defined at the top of the same page as the exercise in Simon's book.
::paul
Cheers, Daniel

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. But you prompt an interesting question: does it make sense to apply foldr to an infinite list? Or rather how is it possible to lazily evaluate foldr? ::paul On Dec 4, 2010, at 2:48 PM, Daniel Fischer wrote:
On Saturday 04 December 2010 23:20:51, Paul Higham wrote:
Not sure if this thread is still active but I also struggled with this same exercise. I offer the following solution as a thing to shoot at:
myInit :: [a] -> [a] myInit ys = foldr snoc [] $ (\(x:xs) -> xs) $ foldr snoc [] ys where snoc = (\x xs -> xs ++ [x])
init === reverse . tail . reverse only holds for finite lists, for infinite lists xs, reverse xs = _| _, but init xs = xs. Also, it's inefficient, but that's not the point of the exercise.
Note that snoc is defined at the top of the same page as the exercise in Simon's book.
::paul
Cheers, Daniel
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

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.
participants (3)
-
dan portin
-
Daniel Fischer
-
Paul Higham