Il left shrinking (or tightening) law says che
mfix (\x -> a >>= \y -> f x y) = a >>= \y -> mfix (\x -> f x y)
In particolare, ciò significa che
mfix (\x -> a' >> f x) = a' >> mfix f
che significa che l'azione monadic all'interno mfix
deve essere valutato esattamente una volta. Questa è una delle proprietà principali di MonadFix
che la tua versione non riesce a soddisfare.
Considerate questo esempio che crea un elenco mutabile ciclico (cerchiamo di non tener conto del fatto che si poteva farlo senza mfix
grazie alla mutevolezza):
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
Con la vostra variante mfix
la chiamata a mrepeat
non finisce mai, come stai chiamando la parte interna con newIORef
indefinitamente.
fonte
2014-09-12 19:30:33
Il monad di continuazione non ha l'operatore del punto di fissaggio desiderato. – augustss
Vedere anche [Perché non può esserci un'istanza di MonadFix per la monade di continuazione?] (Http://stackoverflow.com/q/25827227/1333025). –