我想使用 monads 在 haskell 中编写一个循环,但我很难理解这个概念。
有人可以为我提供一个简单的 while 循环示例,同时满足某些涉及 IO 操作的条件吗?我不想要一个抽象的例子,而是一个真正可行的具体例子。
我想使用 monads 在 haskell 中编写一个循环,但我很难理解这个概念。
有人可以为我提供一个简单的 while 循环示例,同时满足某些涉及 IO 操作的条件吗?我不想要一个抽象的例子,而是一个真正可行的具体例子。
下面有一个可怕的例子。你被警告了。
考虑伪代码:
var x = 23
while (x != 0) {
print "x not yet 0, enter an adjustment"
x = x + read()
}
print "x reached 0! Exiting"
这是它在 Haskell 中的逐段翻译,尽可能使用命令式风格。
import Data.IORef
main :: IO ()
main = do
x <- newIORef (23 :: Int)
let loop = do
v <- readIORef x
if v == 0
then return ()
else do
putStrLn "x not yet 0, enter an adjustment"
a <- readLn
writeIORef x (v+a)
loop
loop
putStrLn "x reached 0! Exiting"
以上确实是可怕的Haskell。它使用递归定义来模拟 while 循环loop
,这还不错。但它在任何地方都使用 IO,包括用于模仿命令式可变变量。
更好的方法可能是删除那些IORef
s。
main = do
let loop 0 = return ()
loop v = do
putStrLn "x not yet 0, enter an adjustment"
a <- readLn
loop (v+a)
loop 23
putStrLn "x reached 0! Exiting"
无论如何都不是优雅的代码,但至少“while guard”现在不会做不必要的 IO。
通常,Haskell 程序员努力尽可能地将纯计算与 IO 分开。这是因为它通常会导致更好、更简单且不易出错的代码。