[Haskell-cafe] Levels of recursion

Yitzchak Gale gale at sefer.org
Thu Feb 1 06:18:42 EST 2007

Hi Andrew,

You wrote:
> combine :: [Int] -> [Int] -> [[Int]]
> combine [] _ = []
> combine (x:xs) ys = (take x ys) : (combine xs (drop x ys))
> ...A much more experienced haskeller told me he
> preferred to write it like this:
> combine' :: [Int] -> [Int] -> [[Int]]
> combine' xs ys = snd $ mapAccumL aux ys xs
>   where aux ys n = (b,a)
>           where (a,b) = splitAt n ys
> Ack!

For real work, I like your version better. I might make it
a little more clear what I am trying to do by writing it as:

combine :: [Int] -> [a] -> [[a]]
combine (x:xs) ys = let (h, t) = splitAt x ys in h : combine xs t
combine _ _ = []

Raw recursions is a bit like goto in imperative programming -
it is often the simplest, but it also can make programs
very difficult to understand.

But as you point out, you can lose more than you gain with
higher-level constructs, unless they are simple, well-documented,
and widely used.

My favorite geeky way of writing your function would be:

combine = evalState . mapM (State . splitAt)

But in real life, I like yours better.


More information about the Haskell-Cafe mailing list