【问题标题】:Is it possible to loop for comprehension with IO是否可以使用 IO 循环理解
【发布时间】:2016-01-23 23:14:48
【问题描述】:

我说的是这个 Haskell 示例:

main = do   
    line <- getLine  
    if null line  
        then return ()  
        else do  
            putStrLn $ reverseWords line  
            main  

是否可以使用IO monad 在 scala 中翻译它?

我想用if 代替return 来理解。我真的不确定用递归调用循环它。听起来 scala 不允许这样做。如果没有,正确的做法是什么?

而且似乎IO 没有filter,即使这样也行不通:

import scalaz._
import effect._
import IO._

for {
   line <- readLn if !line.empty
   _ <- putStrLn(line)
} yield ()

【问题讨论】:

    标签: scala haskell scalaz


    【解决方案1】:

    这在 scala 中是可能的,因为 if 子句在 scala 中也是惰性的。不过,其他涉及惰性求值的技巧可能并不那么直观。

    import scalaz._, effect._, IO._
    
    def main: IO[Unit] = for {
      line <- readLn
      _ <- if (line.isEmpty) {
        Monad[IO].point(())
      } else {
        for {
          _ <- putStrLn(line)
          _ <- main
        } yield ()
      }
    } yield ()
    

    【讨论】:

    • 这听起来不错,但它会导致forward reference extends over definition of value main _ &lt;- main。这与我尝试递归方法时收到的错误相同。但这至少回答了我关于if 的问题。我仍然不会称之为直观:)
    • 啊,我刚刚将val main 变成了def main,这样就可以正常工作了。完美的!我已经修复了答案,希望你不介意
    • @Archeg 由于val 在我的机器上工作和编译,也许我们使用的是不同版本的scala。感谢您的编辑!
    • 仅供参考:我进行了一些调查,看起来只有当它是一个字段时才可能使用 val 作为递归。我将它作为局部变量,这就是它不起作用的原因。 deflazy val 应该始终有效
    猜你喜欢
    • 2019-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-03
    • 2019-03-15
    • 2020-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多