2015-10-13 33 views
0

如何在Haskell中對以下僞代碼進行編碼?在Haskell中的循環中

x=0 
for (i from 0 to 100): 
    j=0 
    while (f(i,j) >0): 
     x+= f(i,j) 
     j+=1 

f一些不重要的功能)

我想出了這樣的事情:

a= [x| i<-[0..100], let s = takeWhile (\k-> (f i k > 0)) [0..], 
     j<- s, let x = f i j ] 

然後Sum a做的工作,但我需要計算f i j兩次這是一個有點多餘。

這可以用f完成,只計算一次或者一些運行得更快的更好的代碼?

回答

2

這裏的一種方式,只爲每對計算f一次:我不喜歡列表理解

inner i = sum $ takeWhile (> 0) $ map (f i) [0..] 
x= sum $ map inner [0..100] 

,尤其是對於更復雜的表達式,所以我發現您的解決方案難以閱讀。主要區別在於,我不是存儲j s的列表,而是存儲了實際的函數值f i j > 0。由於懶惰,這沒有更多的工作。

0

爲了好玩,最直接的翻譯我能想出是:

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 

或者與一些助手:

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