永远的monad如何工作?

dev*_*223 5 haskell

永远的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相关函数.

  • @wshcdr 它忽略结果值但执行副作用。 (3认同)