<div dir="ltr"><div dir="ltr"><div dir="ltr">Hi Benjamin,</div><div dir="ltr"><br></div><div dir="ltr">It's impossible to answer your question without precisely pinning down what you mean by an "embedding." For each monad it is defined for, mfix is required to satisfy three laws: Strictness, Purity, and Left-Shrinking. If you can show that your "embedded" definitions satisfy those, then yes; you do have a valid value-recursion operator. You can find a description of these laws in Chapter 2 of [1]. Since you haven't specified what properties your "embedding" has, it's not possible to say anything in isolation.<div><br></div><div>More traditionally, adding "new" effects to old monads in Haskell is achieved by using monad transformers [2]. Perhaps that's what you have in mind? If that's the case, then Section 4.9 of [1] lays out how mfix from the base monad can be lifted through a monad transformer stack while preserving the properties. If you can cast your design in terms of MTL style transformers, this would be the way to go. And if you do use the MTL package, then you'll have your MonadFix instances for free, since the library already defines them via the usual instance mechanism.</div><div><br></div><div>Cheers,</div><div><br></div><div>-Levent.</div><div><br></div><div>[1] <a href="http://leventerkok.github.io/papers/erkok-thesis.pdf">http://leventerkok.github.io/papers/erkok-thesis.pdf</a></div><div>[2] <a href="https://hackage.haskell.org/package/mtl">https://hackage.haskell.org/package/mtl</a></div></div></div></div><br><div class="gmail_quote"><div dir="ltr">On Thu, Oct 25, 2018 at 7:43 AM Benjamin Redelings <<a href="mailto:benjamin.redelings@gmail.com">benjamin.redelings@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
I'm trying to implement mfix for a monad that is nested inside another <br>
monad.  I came up with the following logic for how to implement this, <br>
but I suspect there are some things I'm missing. My conclusion is that I <br>
want<br>
<br>
interpret (MFix f) = mfix (interpret.f)<br>
<br>
Does this seem right?  Has this situation been discussed somewhere?<br>
<br>
-BenRI<br>
<br>
<br>
P.S. Here's what I mean by the monad being nested in another monad.  <br>
Let's say that the monad M2 has interpreter i2, with type<br>
<br>
i2 :: M2 a -> M1 a<br>
<br>
and then M1 is the other monad, and has interpreter i1:<br>
<br>
i1 :: M1a -> a<br>
<br>
I suppose that the nesting is really a nesting of interpreters.<br>
<br>
<br>
<br>
P.P.S. I came up with some equational reasoning for how to treat mfix in <br>
the i2 interpreter.<br>
<br>
(a) For some interpreters `i`, it makes sense to require<br>
<br>
     i (mfix f) = let x = (i . f) x in x<br>
<br>
(b) I want the composition of interpreters (i1.i2) to act like (a) above:<br>
<br>
     (i1 . i2) (mfix f) = let x = (i1 . i2 . f) x in x<br>
<br>
(c) Rearranging, and then substituting using (a):<br>
<br>
     i1 (i2 (mfix f)) = let x = i1 . (i2 . f) x in x<br>
                            = i1 (mfix (i2 . f))<br>
<br>
(d) Therefore, we could set<br>
<br>
     i2 (mfix f) = mfix (i2 . f)<br>
<br>
I'm probably going to make a `data` declaration for M2 so I could <br>
actually write<br>
<br>
     i2 (Mfix f) = mfix (i2 . f)<br>
<br>
-BenRI<br>
<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
Only members subscribed via the mailman list are allowed to post.</blockquote></div>