2016-09-28 49 views
0

我试图编写一个函数,将不断循环检查,如果一个随机生成的int小于5,如果它小于5那么“e”被附加到一个字符串,一旦“ eee“,然后退出循环。避免可变状态更新字符串

这Haskell代码打印如果1之间的随机值 - 10小于5:

useInt :: Int -> Int 
useInt x = x 

test :: IO() 
test = do 
    let l = "eee"; 
    int <- randomRIO (1, 10) :: IO Int 
    if(int < 5) then   
     putStrLn "less" 
    else 
     putStrLn "greater" 

test 

但是我不能确定如何修改字符串而不引入可变状态。

为了实现这一目标使用伪Haskell代码可以使用:

var mutableString = "" : 

useInt :: Int -> Int 
useInt x = x 

test :: IO() 
test = do 
    let l = "eee"; 
    int <- randomRIO (1, 10) :: IO Int 
    while(mutableString != "eee"){ 
    if(mutableString == "eee") 
     break out of loop 
    else 
     if(int < 5) then 
      mutableString = mutableString + "e" 
      putStrLn "less" 
     else 
      putStrLn "greater" 
    } 
test 

任何指针来翻译上面的伪代码,以有效的Haskell?

回答

5

使用递归:

test :: IO() 
test = let 
    loop "eee" = putStrLn "ending" -- end of the "loop" 
    loop l = do      -- "loop" iteration 
     int <- randomRIO (1, 10) :: IO Int 
     if int < 5 
     then do 
     putStrLn "less" 
     loop l    -- same value for l 
     else do 
     putStrLn "greater" 
     loop ('e':l)   -- updated value for l 
    in loop ""     -- "loop" start with initial value for l 

的想法是,loop l作为一个参数的“可变” l当前值。当我们递归时,我们通过l的新值。在上面的then分支中,我们传递相同的值,因为我们不想修改它。在else分支中,我们添加了'e'字符。