[Haskell-cafe] Computing lazy and strict list operations at the
same time
Robert Dockins
robdockins at fastmail.fm
Mon Jun 19 11:59:29 EDT 2006
On Jun 19, 2006, at 11:24 AM, C Rodrigues wrote:
> Here's a puzzle I haven't been able to solve. Is it possible to
> write the initlast function?
>
> There are functions "init" and "last" that take constant stack
> space and traverse the list at most once. You can think of
> traversing the list as deconstructing all the (:) [] constructors
> in list.
>
> init (x:xs) = init' x xs
> where init' x (y:ys) = x:init' y ys
> init' _ [] = []
>
> last (x:xs) = last' x xs
> where last' _ (y:ys) = last' y ys
> last' x [] = x
>
> Now, is there a way to write initlast :: [a] -> ([a], a) that
> returns the result of init and the result of last, takes constant
> stack space, and traverses the list only once? Calling reverse
> traverses the list again. I couldn't think of a way to do it, but
> I couldn't figure out why it would be impossible.
initlast :: [a] -> ([a],a)
initlast (x:xs) = f x xs id
where
f x (y:ys) g = f y ys (g . (x:))
f x [] g = (g [],x)
Its within the letter, if maybe not the spirit of the rules. The
accumulated function could arguably be considered to be traversing
the list again. FYI, the technique is a fairly well known one for
overcoming the quadratic behavior of repeated (++).
Rob Dockins
Speak softly and drive a Sherman tank.
Laugh hard; it's a long way to the bank.
-- TMBG
More information about the Haskell-Cafe
mailing list