
On Sun, Dec 5, 2010 at 12:37 PM, Hein Hundal
From: Daniel Fischer
Subject: Re: [Haskell-beginners] defining 'init' in terms of 'foldr' 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.
Here is my incomplete beginner solution:
--Start Code
import Data.Maybe myinit v = fromJust $ foldr f Nothing v where f a Nothing = Just [] f a (Just v) = Just (a:v)
--End Code
This worked for the finite lists that I tried, but it did not work for infinite lists. I was surprised that foldr works with infinite lists. If I set
v = take 5 $ foldr (\x xs -> (x*x):xs) [] [1..]
then the value of v is [1,2,9,16]. Is there another way to create the init function with foldr that works for infinite lists?
Keeping your idea but being lazier about it :
myInit v = fromMaybe (error "myInit : empty list") $ foldr f Nothing v where f x xs = Just (case xs of Nothing -> []; Just ys -> x:ys)
-- Jedaï