# [Haskell-cafe] Fwd: Rewrite this imperative in FP way

L Corbijn aspergesoepje at gmail.com
Sun Feb 5 11:00:46 CET 2012

---------- Forwarded message ----------
From: L Corbijn <aspergesoepje at gmail.com>
Date: Sun, Feb 5, 2012 at 10:07 AM
Subject: Re: [Haskell-cafe] Rewrite this imperative in FP way
To: Haisheng Wu <freizl at gmail.com>

On Sun, Feb 5, 2012 at 7:28 AM, Haisheng Wu <freizl at gmail.com> wrote:
> a = [1,1,1,1]
> b = [0,1,2,3]
> d = [0,0,0,0]
>
> for i in b:
>   for j in c:
>     if (i+j)<3:
>       d[i+j] += a[i]
>
> My just work implementation in Haskell
> http://hpaste.org/57452
>
> Another people implementation in Haskell with Monad and it turns out complex
> and very imperatively.
> http://hpaste.org/57358
>
> Do you have any cool solution in FP way?
>
> Thanks.
> -Simon
>
> _______________________________________________
>

Oops forgot to reply to the list,

There are several ways to make it nicer.
Without assumption on what lists a, b and c contain it can be written as
d = [sum \$ map (a !!) [i | i <- b, j <- c, i + j < 3, i + j == dIndex]
| dIndex <- [0..3]]

With the assumption that b and c are both [0..3] this can be 'improved' to
d = (take 3 . map sum . tail \$ inits a) ++ replicate (4 - 3) 0
This generates the first three values by the complicated expression
and then adds the extra zero's by using the replicate expression. This
works as the value of the i-th element of d is the sum over the first
i elements in a if i < 3 and 0 otherwise. A list of lists with the
first i elements is generated with 'tail \$ inits a' which is then
summed and restricted to length 3.
An alternative for this is
d = (take 3 . snd \$ mapAccumL (\acc ai -> (acc + ai, acc + ai)) 0 a)
++ replicate (4 - 3) 0
Where the summation and tail generating is done in the mapAccumL function.

Greetings,
Lars

P.S. Yes the replicate (4-3) 0 can be replaced by [0], but I wanted to
explicitly include the length (4) of the expected list.
P.P.S. for those of you wondering what c is, looking at the solutions in hpaste
c is probably defined as c = [0..3].