我认为问题只是该error信息具有误导性。我们只关注MonadFix Maybe. 参数mfix可以是四件事之一。
在输入中可以是严格的:f _|_ = _|_或者“f需要评估它的输入来决定是否返回Nothing或者Just”
\x -> if x then Nothing else Just True
\x -> x `seq` Nothing
\x -> x `seq` Just x
可以const Nothing。
可以Just . f在f不严格的地方。
Just . (1:)
它可以是严格的Just . f地方。f
Just
如果函数是严格的,那么整个事情就会在无限循环中爆炸(就像fix),并且看不到错误,因为我们不知道我们是否会有 aNothing或 a Just。如果是const Nothing,则该函数实际上从未尝试评估error并且什么也没有发生。如果它是Just . f并且f不严格,那么它只是Just $ fix f(根据法律:)mfix $ return . f = return $ fix f。而且,如果f是严格的,我们得到Just _|_(再次,根据法律)。请注意,我们从未看到error触发。
类似的推理适用于MonadFix (MaybeT m). 我认为这次最好举个例子:
runMaybeT $ mfix $ \x -> MaybeT $
(x `seq` Nothing) :
Nothing :
(Just (1:x)) :
(Just x) :
(x `seq` [])
我上面列出的四个案例中的每一个都在该列表中。结果的第一个元素是无限循环。第二个是Nothing。第三个是repeat 1,第四个是Just无限循环。尝试访问超出此范围的“元素”会触发另一个无限循环,这次是由[]'sMonadFix而不是MaybeT's 引起的。同样,我不相信有可能触发error,因为该函数必须在已经确定结果为 之后强制参数Nothing。