Proposal: Add chop function to Data.List

Isaac Dupree ml at
Wed Dec 15 03:57:17 CET 2010

> 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, 


More information about the Libraries mailing list