繁体   English   中英

永远的monad如何工作?

[英]How does forever monad work?

永远的monad如何工作?

forever :: (Monad m) => m a -> m b
forever a = a >> forever a

如果我写

main = forever $ putStrLn "SAD, I DON'T UNDERSTAND!"

永远得到IO(),这不是函数,怎么能永远反复调用putStrLn?

forever函数的定义中,您可以看到它是一个标准的递归函数。

forever :: (Monad m) => m a -> m b
forever a = a >> forever a

那里没有魔法。 forever只是一个递归函数。 在您的特定情况下,这是一个非终止的。 但它是否成为终止或非终止取决于如何为该类型定义Monad。

检查>>的类型,我们得到:

λ> :t (>>)
(>>) :: Monad m => m a -> m b -> m b

从那里你可以观察到输入ma只是被忽略了。 另一种思考方式是>>函数只执行传递给它的第一个参数的副作用。 在你的情况下, ma将对应于IO ()因为这是putStrLn的类型。

由于IO形成Monad,因此forever功能也可以作用于IO相关功能。

要做的区别是putStrLn "SAD, I DON'T UNDERSTAND!" 是一个行动 ,而不仅仅是一个价值。 它反复执行该动作 无论什么类型的IO a被评估,它都会执行其内部操作,然后返回包含在IO上下文中的类型a 它不必为动作采取参数来做某事。 例如,查看time包中的getCurrentTime函数。 它只有IO UTCTime类型,但如果你多次调用它,你会得到不同的值,即使它没有参数。

暂无
暂无

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

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