将For Loop转换为Haskell

时间:2015-12-16 21:48:40

标签: haskell

我对Haskell相对较新。我理解递归的概念等等。但是,我无法思考如何将类似下面的功能伪代码转换为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是常数)

2 个答案:

答案 0 :(得分:4)

正如所建议的那样,这样做的功能方法是将循环体转换为函数,并返回您感兴趣的变量:

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

答案 1 :(得分:3)

您可以非常轻松地定义一个函数来帮助您编写看起来像命令式循环的东西:

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