MonadPlus 和 forever - 有什么关系?
MonadPlus and forever - what is the relation?
我明白了here
-- Note that "forever" isn't necessarily non-terminating.
-- If the action is in a @'MonadPlus'@ and short-circuits after some number of iterations.
-- then @'forever'@ actually returns `mzero`, effectively short-circuiting its caller.
老实说,我不明白这个注释。它们是否意味着可以用 MonadPlus
打破 forever
,例如 - IO Bool
?比方说,IO False
会破坏它...
从一个角度来看 IO
也是 MonadPlus
。也许我必须将我的 IO Bool
包裹在其他东西中以实现用 IO Bool
和 MonadPlus
打破 forever
的可能性?注释到底是什么意思?
当然,我可以打破它或实现自己的 forever
但我的兴趣是关于这个奇怪的笔记。
可以看看forever
是如何实现的:
forever :: Applicative f => f a -> f b -> f b
forever a = let a' = a *> a' in a'
(*>)
的文档说它“顺序操作,丢弃第一个参数的值”。它基本上是 (>>)
用于 Applicatives 而不是 Monads。
因此,如果您查看 forever
的实现方式,您会发现它基本上扩展为:
forever a = a *> a *> a *> ...
正如 forever
描述所说,如果 Applicative 有一些 short-circuiting 行为,它仍然可以终止并且不会评估无限的动作序列:
ghci> forever $ Nothing
Nothing
ghci> forever $ Just 1
-- infinite loop trying to evaluate Just 1 *> Just 1 *> Just 1 *> ...
那是因为 (Nothing *> _) = Nothing
跟在 (*>)
之后的内容甚至没有被评估,所以 Nothing *> Nothing *> Nothing *> ...
short-circuits 到 Nothing
无需评估无限列表动作数。
人们可能会天真地认为 forever m
会永远持续下去:
forever m = m >> forever m
= m >> m >> forever m
= m >> m >> m >> ... -- forever
但是评论提到有办法打破循环,mzero
是一个简洁的例子,它用方程式而不是从操作上考虑异常来说明情况。 mzero
满足所有 w
的 mzero >> w = mzero
,因此:
forever mzero = mzero >> forever mzero
= mzero
重点是 monad 的选择使得 forever
比命令式语言中的单纯 while (true)
循环更加通用。
我明白了here
-- Note that "forever" isn't necessarily non-terminating.
-- If the action is in a @'MonadPlus'@ and short-circuits after some number of iterations.
-- then @'forever'@ actually returns `mzero`, effectively short-circuiting its caller.
老实说,我不明白这个注释。它们是否意味着可以用 MonadPlus
打破 forever
,例如 - IO Bool
?比方说,IO False
会破坏它...
从一个角度来看 IO
也是 MonadPlus
。也许我必须将我的 IO Bool
包裹在其他东西中以实现用 IO Bool
和 MonadPlus
打破 forever
的可能性?注释到底是什么意思?
当然,我可以打破它或实现自己的 forever
但我的兴趣是关于这个奇怪的笔记。
可以看看forever
是如何实现的:
forever :: Applicative f => f a -> f b -> f b
forever a = let a' = a *> a' in a'
(*>)
的文档说它“顺序操作,丢弃第一个参数的值”。它基本上是 (>>)
用于 Applicatives 而不是 Monads。
因此,如果您查看 forever
的实现方式,您会发现它基本上扩展为:
forever a = a *> a *> a *> ...
正如 forever
描述所说,如果 Applicative 有一些 short-circuiting 行为,它仍然可以终止并且不会评估无限的动作序列:
ghci> forever $ Nothing
Nothing
ghci> forever $ Just 1
-- infinite loop trying to evaluate Just 1 *> Just 1 *> Just 1 *> ...
那是因为 (Nothing *> _) = Nothing
跟在 (*>)
之后的内容甚至没有被评估,所以 Nothing *> Nothing *> Nothing *> ...
short-circuits 到 Nothing
无需评估无限列表动作数。
人们可能会天真地认为 forever m
会永远持续下去:
forever m = m >> forever m
= m >> m >> forever m
= m >> m >> m >> ... -- forever
但是评论提到有办法打破循环,mzero
是一个简洁的例子,它用方程式而不是从操作上考虑异常来说明情况。 mzero
满足所有 w
的 mzero >> w = mzero
,因此:
forever mzero = mzero >> forever mzero
= mzero
重点是 monad 的选择使得 forever
比命令式语言中的单纯 while (true)
循环更加通用。