While in a loop in Haskell

前端 未结 2 991
臣服心动
臣服心动 2021-01-28 20:11

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

(<

相关标签:
2条回答
  • 2021-01-28 21:11

    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 js such that f i j > 0, I stored the actual function value. This does no more work due to laziness.

    0 讨论(0)
  • 2021-01-28 21:12

    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
    
    0 讨论(0)
提交回复
热议问题