如何在其Bool
后面的whileM_
部分中使用作用域的变量?
例如:
guess :: IO ()
guess = do
putStrLn "Please input your guess."
whileM_
(do
guess <- getLine
return (guess /= "secret"))
(do
putStrLn ("You guessed: " ++ guess)
putStrLn ("And " ++ guess ++ " is wrong."))
putStrLn "Right - Bye..."
guess
不在第二个do
块的范围内,因此无法使用。
如何将其纳入范围?
谢谢。
答案 0 :(得分:4)
whileM_
没有内置的实现方法。那个组合器真的有点限制;正如dfeuer所说,你应该使用递归自己编写循环。或者,使用实际上支持这种信息传递的循环结构:
guess :: IO ()
guess = do
putStrLn "Please input your guess."
whileJust_
(do
lastGuess <- getLine -- don't use the name `guess` if that's already a global function name!
return $ if lastGuess /= "secret"
them Just lastGuess else Nothing )
(\lastGuess -> do
putStrLn $ "You guessed: " ++ lastGuess
putStrLn $ "And " ++ lastGuess ++ " is wrong." )
putStrLn "Right - Bye..."
但是 还可以在whileM_
的条件和执行部分之间传递值。两个选项:
特别是IO
,您可以随时使用IORef
s。
guess :: IO ()
guess = do
putStrLn "Please input your guess."
bestGuess <- newIORef ""
whileM_
(do lastGuess <- getLine
writeIORef bestGuess lastGuess
return $ lastGuess /= "secret" )
(do lastGuess <- readIORef bestGuess
putStrLn $ "You guessed: " ++ lastGuess
putStrLn $ "And " ++ lasyGuess ++ " is wrong." )
putStrLn "Right - Bye..."
这在Haskell中更为谨慎 - IORef
基本上是一个可变变量 - 但有时它是明智的。绝对不是一个好主意。
您可以代替IO
使用具有纯功能状态变量的专用monad。这需要a monad transformer。这是一种稍微先进的技术,但对于复杂的应用程序可以很好地解决。