如何打破Haskell的循环? [英] How do I break out of a loop in Haskell?

查看:140
本文介绍了如何打破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)
}

推荐答案

看起来像,或者使用与原始示例类似的do-notation:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆