On Sun, Mar 22, 2009 at 12:26:35PM -0400, Sean Bartell wrote:

> splitWith p xs = let (ls, ts) = f xs in ts:ls

> where f [] = ([], [])

> f (x:xs) | p x = (ls, x:ts)

> | otherwise = (ts:ls, [])

> where (ls, ts) = f xs

>

> splitWith2 p xs = let (ls, ts) = foldr f ([],[]) xs in ts:ls

> where f x (ls, ts) | p x = (ls, x:ts)

> | otherwise = (ts:ls, [])

>

[snip]

> Don't they have the same recursive structure, though?

Err, no. In 'splitWith' you use 'where (ls, ts) = f xs', which means

that you are binding 'ls' and 'ts' lazily, while on 'splitWith2' you

use a pattern in the argument, which is strict. Being strict means

that you need to traverse the whole list in order to produce any

results. If you want to pattern match lazily, you just need to use an

irrefutable pattern, changing 'f x (ls, ts)' to 'f x ~(ls, ts)'.

And, just for the record, I'd prefer to write the function in

semi-pointfree style, as in

> splitWith3 p = uncurry (:) . foldr f ([],[])

> where f x ~(ts, ls) | p x = (x:ts, ls)

> | otherwise = ([], ts:ls)

HTH,

--

Felipe.