Haskell 中使用 monad 的 while 循环示例
Example of while loop in Haskell using monads
我想使用 monad 在 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中的piece-by-piece翻译,尽可能使用命令式风格。
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。它使用 recursively-defined loop
模拟 while 循环,这还不错。但它到处都使用 IO,包括模仿 imperative-style 可变变量。
更好的方法是删除那些 IORef
。
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 分开。这是因为它通常会导致更好、更简单和更少的 error-prone 代码。
我想使用 monad 在 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中的piece-by-piece翻译,尽可能使用命令式风格。
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。它使用 recursively-defined loop
模拟 while 循环,这还不错。但它到处都使用 IO,包括模仿 imperative-style 可变变量。
更好的方法是删除那些 IORef
。
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 分开。这是因为它通常会导致更好、更简单和更少的 error-prone 代码。