Haskell: REPL 的 for 循环
Haskell: a for loop for a REPL
我正在尝试在 Haskell 中编写类似 repl 的东西,我想在 C:
中复制此代码
for (int c = getc(stdin); c != 'e'; c = getc(stdin)) {
printf("I got %c!\n", c);
}
我可以使用递归,但我担心超出限制。
您应该使用递归。 Haskell 旨在无限制地处理递归,递归可以而且应该用于有效的无限循环(例如,事件处理循环或 REPL 循环)。
因此,您可以或多或少地编写如下程序:
main = do
txt <- getLine
if txt /= "exit" then do
putStrLn $ "I got " ++ txt ++ "!"
main
else do
return ()
给予:
$ ./repl
foo
I got foo!
bar
I got bar!
exit
$
我编写它是为了抓取整行输入而不是单个字符,因为在尝试逐字符抓取输入时缓冲输入通常会出现问题。这种无限递归工作正常,无论它在退出前处理了多少亿行都不会超过任何限制。
在大多数 real-world 程序中,您不希望整个主程序循环,因此您通常会编写如下内容。在这里,我使用了 when
,这是一种更好看的方式来编写模式 if xxx then yyy else return ()
.
import Control.Monad -- for definition of "when"
main = do
-- initialization
putStrLn $ "Welcome to my REPL!"
-- start the main loop
loop
-- clean up
putStrLn $ "Thanks so much for using my REPL!"
-- definition of main loop
loop = do
txt <- getLine
when (txt /= "exit") $ do
putStrLn $ "I got " ++ txt ++ "!"
loop
我正在尝试在 Haskell 中编写类似 repl 的东西,我想在 C:
中复制此代码for (int c = getc(stdin); c != 'e'; c = getc(stdin)) {
printf("I got %c!\n", c);
}
我可以使用递归,但我担心超出限制。
您应该使用递归。 Haskell 旨在无限制地处理递归,递归可以而且应该用于有效的无限循环(例如,事件处理循环或 REPL 循环)。
因此,您可以或多或少地编写如下程序:
main = do
txt <- getLine
if txt /= "exit" then do
putStrLn $ "I got " ++ txt ++ "!"
main
else do
return ()
给予:
$ ./repl
foo
I got foo!
bar
I got bar!
exit
$
我编写它是为了抓取整行输入而不是单个字符,因为在尝试逐字符抓取输入时缓冲输入通常会出现问题。这种无限递归工作正常,无论它在退出前处理了多少亿行都不会超过任何限制。
在大多数 real-world 程序中,您不希望整个主程序循环,因此您通常会编写如下内容。在这里,我使用了 when
,这是一种更好看的方式来编写模式 if xxx then yyy else return ()
.
import Control.Monad -- for definition of "when"
main = do
-- initialization
putStrLn $ "Welcome to my REPL!"
-- start the main loop
loop
-- clean up
putStrLn $ "Thanks so much for using my REPL!"
-- definition of main loop
loop = do
txt <- getLine
when (txt /= "exit") $ do
putStrLn $ "I got " ++ txt ++ "!"
loop