[Haskell-cafe] Rewrite this imperative in FP way

Roman Cheplyaka roma at ro-che.info
Sun Feb 5 10:20:35 CET 2012


* Haisheng Wu <freizl at gmail.com> [2012-02-05 14:28:10+0800]
> 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]
> 
> Do you have any cool solution in FP way?

You can use IntMap as a replacement for arrays:
(I didn't understand your algorithm exactly, since you use 'c', which is
not defined, but hopefully this is close enough)

    import Control.Monad
    import Data.List
    import Data.IntMap as IntMap

    a = [1,1,1,1]
    b = [0,1,2,3]
    c = IntMap.fromList $ zipWith (,) [0..] a

    d = foldl' f IntMap.empty $ liftM2 (,) a b
        where
            f m (i, j) =
                let s = i+j in
                if s < 3 then IntMap.insertWith (+) s (c ! i) m else m

    main = print d

A single non-obvious thing here is "liftM2 (,) a b" -- it builds the
cartesian product of lists a and b and is used here to replace your
nested loops.

-- 
Roman I. Cheplyaka :: http://ro-che.info/



More information about the Haskell-Cafe mailing list