简体   繁体   English

在Haskell中使用什么而不是主循环?

[英]What to use instead of a main loop in Haskell?

I need a loop for main in Haskell. 我在Haskell中需要一个main循环。 I've tried this: 我试过这个:

main :: IO ()
main =
  do
    putStrLn "do something"
    main

Is the above code the correct approach to take? 上面的代码是正确的方法吗? Will this infinite recursion cause an overflow? 这种无限递归会导致溢出吗?

This is fine; 这可以; no stack overflow will occur. 不会发生堆栈溢出。 Stack overflows in Haskell (and, indeed, any non-strict language) are different to those in other languages; Haskell中的堆栈溢出(实际上,任何非严格的语言)与其他语言中的堆栈溢出不同; they arise from accumulating large values without ever evaluating them, but you're not accumulating anything here; 它们是在没有评估它们的情况下积累大量价值而产生的,但你们并没有在这里积累任何东西; just sequencing an infinite chain of actions. 只是排序一系列无限的动作。 You can think of it like this: Once the line is printed, the action is discarded, and control passes straight onto main ; 您可以这样想:打印线后,操作被丢弃,控制直接传递到main ; nothing is kept on the stack because there's nothing that has to be returned to. 没有任何东西保留在堆栈上,因为没有什么必须返回。

It's the same reason you can iterate through an infinite list without running out of memory: as the program goes further down the list, previous list cells are reclaimed by the garbage collector as they're no longer required. 这就是你可以在不耗尽内存的情况下迭代无限列表的原因相同:当程序进一步向下列表时,垃圾收集器会回收先前的列表单元格,因为它们不再需要。 In this case, the previous sequencings are reclaimed, as there's no reason to keep around an action you've already performed. 在这种情况下,之前的顺序被回收,因为没有理由保留您已执行的操作。

That said, a nicer way to write this particular example is: 也就是说,编写这个特定示例的更好方法是:

import Control.Monad

main :: IO ()
main = forever $ putStrLn "do something"

Of course, this won't work if your loop is ever intended to terminate. 当然,如果您的循环有意终止,这将不起作用。 forever is itself implemented with recursion, so there's no benefit other than readability to doing this. forever本身就是用递归来实现的,所以除了可读性之外没有任何好处。

What you observe is the result of "tail call elimination / optimization", which is nothing special to Haskell. 您观察到的是“尾调用消除/优化”的结果,这对Haskell来说并不特别。 See eg http://en.wikipedia.org/wiki/Tail_call 参见例如http://en.wikipedia.org/wiki/Tail_call

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM