由于每个Nothing >>= f = Nothing
都有f
,因此以下简单定义适用于mfix
:
mfix _ = Nothing
但这没有实际用途,因此我们有以下非总计定义:
mfix f = let a = f (unJust a) in a where
unJust (Just x) = x
unJust Nothing = errorWithoutStackTrace "mfix Maybe: Nothing"
如果
mfix f
-clause不停止,则Nothing
返回let
会很好。 (例如f = Just . (1+)
)因为停止问题无法解决,这是否不可能?
最佳答案
MonadFix
律之一说,当单子(monad)动作是纯函数时,单子(monad)定点必须与纯定点重合:
mfix (return . f) = return (fix f)
因此,需要执行以下操作:
mfix (Just . (1+)) = mfix (return . (1+))
= return (fix (1+))
= Just (fix (1+))
fix (1+)
确实是最底层的。因此,对于您建议的功能,法律明确规定了mfix
必须如何行为(并且确实如此)。与实例是否遵守法律无关,我们可以询问我们是否喜欢法律,或者具有您所提议的行为,具有不同名称和法律的另一功能是否有用?例如特别是这两个调用的行为应如下所示:
mfix' (Just . (1+)) = Nothing
mfix' (Just . const 1) = Just 1
由于您所说的确切原因,这是不可能实现的:暂停问题告诉我们,无法确定
fix f
是否会循环或结束任意f
。我们可以通过多种方式来逼近此函数,但是在这方面,所有函数最终都将不尽人意。