
chop :: ([a] -> (b, [a])) -> [a] -> [b] chop _ [] = [] chop f as = b : chop f as' where (b, as') = f as
Let's compare with an existing similar function, unfoldr. (This is a somewhat academic exploration.) unfoldr :: (c -> Maybe (d, c)) -> c -> [d] c=[a],d=b: ([a] -> Maybe (b, [a])) -> [a] -> [b] chop :: ([a] -> (b, [a])) -> [a] -> [b] In unfoldr, termination is signalled after 'f' and before a value is emitted. In unfoldr, termination is signalled before 'f' by an empty list, even though the list is passed intact to 'f'. That seems peculiar. But it's what we want. 'f' in 'chop' is usually a function that picks an 'n' somehow and yields (g (take n as), drop n as) for f's corresponding 'g', but does it efficiently. Clearly this is boring for an empty list, as (g [], []) would be a repeating constant forever under these conditions. 'f' *can* be different though. It can take into account more of the list than is consumed (e.g. tokenizing "this+that" needs to look at the + before returning "this"): that's pretty common. I wonder if there are any common examples where the returned list /= (drop n as) for some n, though. -Isaac