目标:取一个字符串并在控制台中打印相同的东西,就像需要永远完成相同的操作一样
我提出了这样的事情,没有编译错误但没有按预期工作.
greet_buggy :: String -> IO ()
greet_buggy = forever $ putStrLn
Run Code Online (Sandbox Code Playgroud)
问题是在字符串下面没有在控制台中打印任何内容.
greet_buggy "something"
Run Code Online (Sandbox Code Playgroud)
基于这篇文章我尝试调试并更改了如下定义.它工作正常
greet :: IO ()
greet = forever $ putStrLn "Hello"
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释这里发生的事情吗?是否有可能forever单独使用相同的效果?
编辑:找到一个相关的帖子(感谢@Daniel Wagner),即使通过这个问题与我的不同,答案解释一下forever.
greet_buggy 正在为一个不同的monad工作.
forever采取一元行动并无限期地重复它.它可以这样定义:
forever a = let loop = a >> loop in loop
Run Code Online (Sandbox Code Playgroud)
也可以看作是
forever a = a >> a >> a >> a >> ... (infinitely many times)
Run Code Online (Sandbox Code Playgroud)
(事实上永远是定义在Applicative,而不是Monad;但现在这并不重要).
所以forever greet实际上是
putStrLn "Hello" >> putStrLn "Hello" >> putStrLn "Hello" >> ...
Run Code Online (Sandbox Code Playgroud)
这不需要进一步解释.
OTOH forever greet_buggy相当于
putStrLn >> putStrLn >> putStrLn >> ...
Run Code Online (Sandbox Code Playgroud)
现在,因为(-> a)是一个monad,>>定义为任何两个合适类型的函数,f >> g在这种情况下的含义是......只是g!所以意义
( putStrLn >> putStrLn >> putStrLn >> ... ) "Hello"
Run Code Online (Sandbox Code Playgroud)
是采取链中的最后一个函数>>并将其应用于Hello.当然,那里没有最后的功能,所以这只是永远运行.
| 归档时间: |
|
| 查看次数: |
873 次 |
| 最近记录: |