为什么/递归IO如何工作? [英] Why/how does recursive IO work?
问题描述
main
),它返回一个IO值(通常被描述为一个命令式IO程序),它然后由运行时执行。 这个心智模型对于简单的例子来说很好,但是当我看到一个递归的 main
在学习你一个Haskell 。例如:
main = do
line< - getLine
putStrLn line
main
或者,如果您愿意:
main = getLine>> = putStrLn>>主要
由于主要
永不终止,实际上返回一个IO值,然而程序无休止地读取和回显行就好了 - 所以上面的简单解释并不是很有效。我是否错过了一些简单的东西或者是否有更完整的解释(或者它只是'编译器的魔力')? 情况下, main
是类型 IO()
的值,而不是函数。你可以把它看作一系列 IO a
值:
main = getLine>> = putStrLn>> main
这使得它成为递归值,与无限列表不同:
foo = 1:2:foo
<我们可以返回这样的值,而不需要评估整个事情。事实上,这是一个相当常见的习惯用语。
main
也是如此:除非使用某种外部方法来突破它,否则它将永远不会停止循环!但是你可以开始从 foo
中获取元素,或者执行 main
的部分,而不对它进行全部评估。 p> Haskell IO is often explained in terms of the entire program being a pure function (main
) that returns an IO value (often described as an imperative IO program), which is then executed by the runtime.
This mental model works fine for simple examples, but fell over for me as soon as I saw a recursive main
in Learn You A Haskell. For example:
main = do
line <- getLine
putStrLn line
main
Or, if you prefer:
main = getLine >>= putStrLn >> main
Since main
never terminates, it never actually returns an IO value, yet the program endlessly reads and echoes back lines just fine - so the simple explanation above doesn't quite work. Am I missing something simple or is there a more complete explanation (or is it 'simply' compiler magic) ?
In this case, main
is a value of type IO ()
rather than a function. You can think of it as a sequence of IO a
values:
main = getLine >>= putStrLn >> main
This makes it a recursive value, not unlike infinite lists:
foo = 1 : 2 : foo
We can return a value like this without needing to evaluate the whole thing. In fact, it's a reasonably common idiom.
foo
will loop forever if you try to use the whole thing. But that's true of main
too: unless you use some external method to break out of it, it will never stop looping! But you can start getting elements out of foo
, or executing parts of main
, without evaluating all of it.
这篇关于为什么/递归IO如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!