如何打破Haskell的循环? [英] How do I break out of a loop in Haskell?
问题描述
管道教程的当前版本,在示例之一中使用以下两个功能:
The current version of the Pipes tutorial, uses the following two functions in one of the example:
stdout :: () -> Consumer String IO r
stdout () = forever $ do
str <- request ()
lift $ putStrLn str
stdin :: () -> Producer String IO ()
stdin () = loop
where
loop = do
eof <- lift $ IO.hIsEOF IO.stdin
unless eof $ do
str <- lift getLine
respond str
loop
在本教程中已经提到过,由于需要检查输入的结尾,P.stdin稍微复杂一些.
As is mentinoed in the tutorial itself, P.stdin is a bit more complicated due to the need to check for the end of input.
有没有什么好办法可以重写P.stdin而不需要手动尾递归循环,而可以使用像P.stdout这样的高阶控制流组合器呢?在命令式语言中,我将使用结构化的while循环或break语句执行相同的操作:
Are there any nice ways to rewrite P.stdin to not need a manual tail recursive loop and use higher order control flow combinators like P.stdout does? In an imperative language I would use a structured while loop or a break statement to do the same thing:
while(not IO.isEOF(IO.stdin) ){
str <- getLine()
respond(str)
}
forever(){
if(IO.isEOF(IO.stdin) ){ break }
str <- getLine()
respond(str)
}
推荐答案
or, using do-notation similarly to the original example:
stdin () =
whileM_ (lift . fmap not $ IO.hIsEOF IO.stdin) $ do
str <- lift getLine
respond str
monad-loops
包还提供了whileM
,它返回了中间列表结果,而不是忽略重复操作和其他有用的组合器的结果.
The monad-loops
package offers also whileM
which returns a list of intermediate results instead of ignoring the results of the repeated action, and other useful combinators.
这篇关于如何打破Haskell的循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!