[Haskell-cafe] Rewrite this imperative in FP way

Thomas Hallgren hallgren at altocumulus.org
Mon Feb 6 15:59:01 CET 2012


How about this:

  import Array

  a = [1,1,1,1]
  b = [0,1,2,3]
  c = [0,2]

  d = elems $ accumArray (+) 0 (0,3) [(i+j,a!!i) | i<-b, j<-c, i+j<3]


--
Thomas H

On 2012-02-06 12:01 , Haisheng Wu wrote:
> *d = [sum $ map (a !!) [i | i <- b, j <- c, i + j < 3, i + j == dIndex] | dIndex
> <- [0..3]] *
> 
> This is cool.
> 
> -Simon
> 
> 
> On Sun, Feb 5, 2012 at 5:07 PM, L Corbijn <aspergesoepje at gmail.com
> <mailto:aspergesoepje at gmail.com>> wrote:
> 
>     On Sun, Feb 5, 2012 at 7:28 AM, Haisheng Wu <freizl at gmail.com
>     <mailto: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
>     >
>     > _______________________________________________
>     > Haskell-Cafe mailing list
>     > Haskell-Cafe at haskell.org <mailto:Haskell-Cafe at haskell.org>
>     > http://www.haskell.org/mailman/listinfo/haskell-cafe
>     >
> 
>     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.
> 
> 
> 
> 
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe





More information about the Haskell-Cafe mailing list