How to code the following pseudo-code in Haskell?
x=0
for (i from 0 to 100):
j=0
while ( f(i,j) >0 ):
x+= f(i,j)
j+=1
(<
Here's a way that only computes f
once for each pair:
inner i = sum $ takeWhile (> 0) $ map (f i) [0..]
x= sum $ map inner [0..100]
I dislike list comprehensions, especially for more complex expressions, so I found your solution difficult to read. The primary difference is that instead of storing a list of j
s such that f i j > 0
, I stored the actual function value. This does no more work due to laziness.
For fun the most direct translation I could come up with was:
f i j = 100 - i - j
test x =
foldr (\i ->
foldr (\j g ->
let y = f i j in
if y > 0 then g . (+ y) else id
) id [0..]
) x [0..100]
x = test 0
Or with some helpers:
f i j = 100 - i - j
for :: (Enum i) => i -> i -> (i -> a -> a) -> a -> a
for i1 i2 f x = foldr f x [i1..i2]
while :: i -> (i -> i) -> (i -> Bool) -> (i -> a -> a) -> a -> a
while i s p f x =
foldr (\i g x ->
if p i then g (f i x) else x
) id (iterate s i) x
test =
for 0 100 $ \i ->
while 0 (+ 1) (\j -> f i j > 0) $ \j x ->
x + f i j
x = test 0