Hi,

I am new to Haskell (and programming). Thompson's exercise 9.13  in Craft of Functional Programming gave me trouble. Searching the list archives, I saw people define init (xs), last (xs), and so on, in a variety of complex ways (using the Maybe monad, using fairly complex post-processing). This seems to be a hard problem for beginners; at least, it was rather hard for me.

The problem is to define the Prelude functions init and last using foldr. After a while, I came up with:

-- *Exercise 9.13*: Use foldr (f, s, xs) to give definitions of the prelude functions
-- unzip, last, and init.

-- Clearly,
--     [(x, y), (x1, y1)] = (x, y) : (x1, y1) : ([], [])
--     foldr f ([], []) ((x, y):(x1, y1):[]) = f (x, y) (f (x1, y1) ([], []))
-- Hence, f (x, y) (xs, ys) must equal (x:xs, y:ys) for any xs, ys.

unzip :: [(a, b)] -> ([a], [b])
unzip xys = foldr f ([], []) xys
 where f :: (a, b) -> ([a], [b]) -> ([a], [b])
       f (x, y) (xs, ys) = (x:xs, y:ys)

last :: [a] -> a      
last xs = head $ foldr f [] xs
 where f :: a -> [a] -> [a]
       f x [] = [x]
       f x ys = ys ++ [x]

init :: [a] -> [a]
init xs = tail $ foldr f [] xs
 where f :: a -> [a] -> [a]
       f x [] = [x]
       f x (y:xs) = y : x : xs

Now, these seemed to be hard questions. So, I have three questions: (1) are these correct? They work on test cases, and I did do some quick proofs. They seem okay. (2) Is there a way to eliminate the post-processing of the lists (i.e., head in last and tail in init)? (3) Why the complex answers in the list archives? Am I missing something?