
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?