为什么`mfix`在MaybeT中不总计 [英] Why is `mfix` not total in `MaybeT`

查看:115
本文介绍了为什么`mfix`在MaybeT中不总计的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

The transformers implementation of MonadFix for MaybeT fails if the function ever evaluates to Nothing. Why is Nothing not propagating over mfix?

mfix' :: MonadFix m => (a -> MaybeT m a) -> MaybeT m a
mfix' f = MaybeT $ mfix $ \case
  Nothing -> return Nothing
  Just x -> runMaybeT $ f x

有一个很好的理由使我看不到,因为ListT根本没有实现MonadFix,而Maybe却实现了

There must be a good reason that I do not see because ListT does not implement MonadFix at all, and Maybe implements it in the same way as above.

推荐答案

我认为问题只是error消息具有误导性.让我们只关注MonadFix Maybe. mfix的参数可以是以下四项之一.

I think the issue is just that the error message is misleading. Let's just focus on MonadFix Maybe. The argument to mfix can be one of four things.

  1. 输入中可能很严格:f _|_ = _|_或"f需要评估其输入以确定是否返回NothingJust"

  1. It can be strict in the input: f _|_ = _|_ or "f needs to evaluate its input to decide whether it will return Nothing or 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:)
    

  • 其中f严格的地方可能是Just . f.

  • It can be Just . f where f is strict.

    Just
    

  • 如果函数很严格,那么整个过程将无限循环地崩溃(就像fix一样),并且因为我们不知道是否会出现Nothing或其他原因,所以看不到错误. Just.如果它是const Nothing,则该函数实际上不会尝试评估error,并且什么也没有发生.如果它是Just . ff不严格,则它只是Just $ fix f(根据法律:mfix $ return . f = return $ fix f).而且,如果f是严格的,我们将得到Just _|_(再次根据法律).请注意,我们从未看到error被触发.

    If the function is strict, then the whole thing blows up in an infinite loop (just like fix), and the error isn't seen because we don't know whether we would have had a Nothing or a Just. If it is const Nothing, the function never actually tries to evaluate the error and nothing happens. If it is Just . f and f is not strict, then it's just Just $ fix f (as per the laws: mfix $ return . f = return $ fix f). And, if f is strict, we get Just _|_ (again, per the laws). Notice that we never see the error triggered.

    类似的推理适用于MonadFix (MaybeT m).我认为这一次最好举个例子:

    Similar reasoning works for MonadFix (MaybeT m). I think this time it's better just with an example:

    runMaybeT $ mfix $ \x -> MaybeT $
                 (x `seq` Nothing) :
                 Nothing           :
                 (Just (1:x))      :
                 (Just x)          :
                 (x `seq` [])
    

    我上面列出的四种情况中的每一种都在该列表中.结果的第一个元素是无限循环.第二个是Nothing.第三个是repeat 1,第四个是Just无限循环.尝试访问超出此范围的元素"会触发另一个无限循环,这一次是由[]MonadFix而不是MaybeT引起的.同样,我不认为有可能触发error,因为该函数在已经确定结果为Nothing之后必须强制使用参数.

    Each of the four cases I listed above are in that list. The first element of the result is an infinite loop. The second is Nothing. The third is repeat 1, and the fourth is Just an infinite loop. Trying to access the "elements" beyond that triggers another infinite loop, this time caused by []'s MonadFix and not MaybeT's. Again, I don't believe it's possible to trigger the error, because the function would have to force the argument after already deciding that the result was Nothing.

    这篇关于为什么`mfix`在MaybeT中不总计的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆