我對Haskell比較新。我理解遞歸等概念。但是,我無法通過如何類似下面的功能的僞代碼轉換爲Haskell的思考:Convert For Loop to Haskell
x = 0
y = 0
For Count = 1 To 100 {
Print (Count, x, y)
z = -(A*x + B*y)/C - D
x = x + y
y = y + z`
}
(注意A,B,C,d爲常數)
我對Haskell比較新。我理解遞歸等概念。但是,我無法通過如何類似下面的功能的僞代碼轉換爲Haskell的思考:Convert For Loop to Haskell
x = 0
y = 0
For Count = 1 To 100 {
Print (Count, x, y)
z = -(A*x + B*y)/C - D
x = x + y
y = y + z`
}
(注意A,B,C,d爲常數)
你可以很容易地定義一個函數幫你寫的東西看起來像命令式的循環:
import Control.Monad
loop :: Monad m => [i] -> a -> (i -> a -> m a) -> m a
loop is a0 f = foldr (>=>) return (map f is) a0
的定義並不重要(很多很多的方式來寫這個功能),而是要了解它做什麼,看的類型。給定一些列表i
- 要循環的值的範圍,以及您的循環的一些初始值,a
,最後,一個給定值(i
)和循環狀態(a
)的函數返回一個新的循環狀態在某些情況下m
。這個函數在上下文中產生一個計算結果m
,它產生最後一個狀態。
使用它只是像這樣:
import System.Environment
main = do
(c0:c1:c2:c3:_) <- map read <$> getArgs
loop [1..100] (0,0) $ \count (x,y) -> do
print (count,x,y)
let z = -(c0*x + c1*y)/c2 - c3
return (x+y,y+z)
和
> runghc test.hs 12 34 56 78
如所建議的,這樣的功能的方法是把你的循環體成函數將返回的變量,你」重新關注:
f (x, y) =
let
z = -(a*x + b*y)/c - d
x' = x + y
y' = y + z
in
(x', y')
然後,您可以將函數應用到自身100次(0,0)
作爲起始值:
values = take 100 $ iterate f (0,0)
然後,可選,傾倒所有的中間值,毫不客氣地在屏幕上:
main = print values
我知道如何編寫一個函數,遞歸調用它的基本情況,所以我可以迭代一個數字列表並對每個數字進行一些操作。我很難找出如何通過遞歸來攜帶變量x和y的值,因爲在基本情況下計算x和y(count = 100)需要來自以前循環迭代的x和y的值。 – JeffC
不是更新變量,而是將循環體看作一個函數,它接受兩個變量'(x,y)'並返回兩個變量'(x',y')'。然後你的循環被應用於自己的輸出100次。 –
可能的重複[如何使用遞歸嵌套for循環haskell沒有forloop](http://stackoverflow.com/questions/26203493/how-to-use-recursion-nested-for-loop-in-haskell-without- forloop) – jberryman