永远的monad如何工作?
forever :: (Monad m) => m a -> m b
forever a = a >> forever a
Run Code Online (Sandbox Code Playgroud)
如果我写
main = forever $ putStrLn "SAD, I DON'T UNDERSTAND!"
Run Code Online (Sandbox Code Playgroud)
永远得到IO(),这不是函数,怎么能永远反复调用putStrLn?
Sib*_*ibi 11
从forever函数的定义,您可以看到它是一个标准的递归函数.
forever :: (Monad m) => m a -> m b
forever a = a >> forever a
Run Code Online (Sandbox Code Playgroud)
那里没有魔法.forever只是一个递归函数.在您的特定情况下,这是一个非终止的.但它是否成为终止或非终止取决于如何为该类型定义Monad.
检查类型>>,我们得到:
?> :t (>>)
(>>) :: Monad m => m a -> m b -> m b
Run Code Online (Sandbox Code Playgroud)
从那以后你可以观察到输入m a被忽略了.另一种思考方式是>>函数只执行传递给它的第一个参数的副作用.在你的情况下,m a将对应于,IO ()因为这是类型putStrLn.
由于IO形成Monad,因此forever函数也可以作用于IO相关函数.