On Tue, Apr 19, 2011 at 11:48 PM, Tyson Whitehead <twhitehead@gmail.com> wrote:
On April 19, 2011 23:22:12 Tyson Whitehead wrote:
> ArrowLoop from MonadFix
>
> loop' f = fst' .' loop'' (f .' arr' (second snd))
> where loop'' f = mfix (\y -> f .' arr' (,y))
BTW haskellers, I've been wondering if mfix would better be defined as
mfix' :: (m a -> m a) -> m a
where "mfix' f = mfix (f . pure)" for the computational monads. The advantage
being you can give a useful definition for structural monads as well.
Note: This does not generalize the signature of mfix, it only overlaps slightly, as not every monad m permits the extraction of the value a injected (consider Cont r), so you necessarily change the meaning or obliterate a number of instances.
Recall the main motivation for mfix was to support Erkoek and Launchbury's recursive do:
This necessitates 4 laws for mfix, which don't translate nicely.
mfix (return . h) = return (fix h)
-
mfix (\x -> a >>= \y -> f x y) = a >>= \y -> mfix (\x -> f x y)
-
if is strict,
mfix (liftM h . f) = liftM h (mfix (f . h))
-
mfix (\x -> mfix (\y -> f x y)) = mfix (\x -> f x x)
The other commonly proposed mfix replacement is to define it once, as guided by the types, but while this works for fix and the the comonadic equivalent, it doesn't generate a useful mfix for recursive do either.
-Edward