Die left shrinking (or tightening) law says dass
mfix (\x -> a >>= \y -> f x y) = a >>= \y -> mfix (\x -> f x y)
Insbesondere bedeutet dies, dass
mfix (\x -> a' >> f x) = a' >> mfix f
was bedeutet, daß die monadische Aktion innerhalb mfix
muss genau einmal ausgewertet werden. Dies ist eine der Haupteigenschaften von MonadFix
, die Ihre Version nicht erfüllen kann.
dieses Beispiel betrachten, die eine zyklische wandelbar Liste erstellt (lassen Sie uns die Tatsache außer Acht lassen, dass Sie tun können, dass ohne mfix
dank Veränderlichkeit):
import Control.Monad
import Control.Monad.Fix
import Data.IORef
data MList a = Nil | Cons a (IORef (MList a))
mrepeat :: a -> IO (MList a)
mrepeat x = mfix (liftM (Cons x) . newIORef)
main = do
(Cons x _) <- mrepeat 1
print x
Mit Ihrer Variante mfix
der Anruf an mrepeat
nie beendet, als Du rufst den inneren Teil mit newIORef
auf unbestimmte Zeit an.
Die Fortsetzungs-Monade hat nicht den gewünschten Fixpunktoperator. – augustss
Siehe auch [Warum kann es keine Instanz von MonadFix für die Continuation-Monade geben?] (Http://stackoverflow.com/q/25827227/1333025). –