<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<div style="" data-md-original="<div
class="moz-cite-prefix"><br><br>Dne
06/03/2013 09:11 PM, Henning Thielemann
napsal(a):<br></div><blockquote
cite="mid:alpine.DEB.2.00.1306032109530.12856@anubis.informatik.uni-halle.de"
type="cite">
<br>On Mon, 3 Jun 2013, Edward Kmett wrote:
<br>
<br><blockquote type="cite">The first option
is
<br>
<br>class Monad m =&gt; MonadRef r m | m -&gt; r
where
<br>&nbsp; newRef :: a -&gt; m (r a)
<br>&nbsp; ...
<br>
<br>This has the benefit of using quite portable extensions.
<br>
<br>The second option is
<br>
<br>class Monad m =&gt; MonadRef m where&nbsp; type
Ref m :: * -&gt; *
<br>&nbsp; newRef :: a -&gt; m (Ref m a)
<br>&nbsp;
<br>This takes us into GHC specific territory, by using type
families, but avoids polluting every type that uses
<br>one with an extra 'ref' param. I use this variant in my
as-yet-unreleased 'revisions' package.
<br>
<br>Both of these have the benefit that they can work with
transformers, but they carry the limitation that you
<br>can't have multiple reference types for the same monad.
e.g. you can't use the same combinators for both
<br>IORefs and, say, MVars or TVars within the same monad.
This is arguably not so much a problem as they have
<br>very different operational semantics!
<br></blockquote>
<br>I thought the functional dependency should be the other
way round: From the reference type to the monad where it lives in.
<br>
</blockquote><br>For monads, it's (AFAIK) always this
way, because `m` is always in the result, but not necessarily the
other type. Let's consider<br>```haskell<br>readRef ::
r a -&gt; m a<br>```<br>In order to type-check `x`
in `readRef x`, we need to determine `r a` from `m a`, so the
dependency must be `m -&gt; r`.<br>"
class="markdown-here-wrapper" id="markdown-here-wrapper-314557">
<p style="margin: 1.2em 0px ! important;">Dne 06/03/2013 09:11 PM,
Henning Thielemann napsal(a):</p>
<p style="margin: 1.2em 0px ! important;"></p>
<div class="markdown-here-exclude">
<p></p>
<blockquote
cite="mid:alpine.DEB.2.00.1306032109530.12856@anubis.informatik.uni-halle.de"
type="cite">
<br>
On Mon, 3 Jun 2013, Edward Kmett wrote:
<br>
<br>
<blockquote type="cite">The first option is
<br>
<br>
class Monad m => MonadRef r m | m -> r where
<br>
newRef :: a -> m (r a)
<br>
...
<br>
<br>
This has the benefit of using quite portable extensions.
<br>
<br>
The second option is
<br>
<br>
class Monad m => MonadRef m where type Ref m :: * ->
*
<br>
newRef :: a -> m (Ref m a)
<br>
<br>
This takes us into GHC specific territory, by using type
families, but avoids polluting every type that uses
<br>
one with an extra 'ref' param. I use this variant in my
as-yet-unreleased 'revisions' package.
<br>
<br>
Both of these have the benefit that they can work with
transformers, but they carry the limitation that you
<br>
can't have multiple reference types for the same monad. e.g.
you can't use the same combinators for both
<br>
IORefs and, say, MVars or TVars within the same monad. This
is arguably not so much a problem as they have
<br>
very different operational semantics!
<br>
</blockquote>
<br>
I thought the functional dependency should be the other way
round: From the reference type to the monad where it lives in.
<br>
</blockquote>
<p></p>
</div>
<p style="margin: 1.2em 0px ! important;"></p>
<p style="margin: 1.2em 0px ! important;">For monads, it's (AFAIK)
always this way, because <code style="font-size: 0.85em;
font-family: Consolas,Inconsolata,Courier,monospace;margin:
0px 0.15em; padding: 0px 0.3em; white-space: nowrap; border:
1px solid rgb(234, 234, 234); background-color: rgb(248, 248,
248); border-radius: 3px 3px 3px 3px; display: inline;">m</code>
is always in the result, but not necessarily the other type.
Let's consider</p>
<pre style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;font-size: 1em; line-height: 1.2em; overflow: auto;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px 3px 3px 3px; display: inline;white-space: pre; border-radius: 3px 3px 3px 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em;display: block; padding: 0.5em; color: rgb(51, 51, 51); background: none repeat scroll 0% 0% rgb(248, 248, 255);" class="language-haskell"><span style="color: rgb(153, 0, 0); font-weight: bold;" class="title">readRef</span> :: r a -> m a</code></pre>
<p style="margin: 1.2em 0px ! important;">In order to type-check <code
style="font-size: 0.85em; font-family:
Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em;
padding: 0px 0.3em; white-space: nowrap; border: 1px solid
rgb(234, 234, 234); background-color: rgb(248, 248, 248);
border-radius: 3px 3px 3px 3px; display: inline;">x</code> in
<code style="font-size: 0.85em; font-family:
Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em;
padding: 0px 0.3em; white-space: nowrap; border: 1px solid
rgb(234, 234, 234); background-color: rgb(248, 248, 248);
border-radius: 3px 3px 3px 3px; display: inline;">readRef x</code>,
we need to determine <code style="font-size: 0.85em;
font-family: Consolas,Inconsolata,Courier,monospace;margin:
0px 0.15em; padding: 0px 0.3em; white-space: nowrap; border:
1px solid rgb(234, 234, 234); background-color: rgb(248, 248,
248); border-radius: 3px 3px 3px 3px; display: inline;">r a</code>
from <code style="font-size: 0.85em; font-family:
Consolas,Inconsolata,Courier,monospace;margin: 0px 0.15em;
padding: 0px 0.3em; white-space: nowrap; border: 1px solid
rgb(234, 234, 234); background-color: rgb(248, 248, 248);
border-radius: 3px 3px 3px 3px; display: inline;">m a</code>,
so the dependency must be <code style="font-size: 0.85em;
font-family: Consolas,Inconsolata,Courier,monospace;margin:
0px 0.15em; padding: 0px 0.3em; white-space: nowrap; border:
1px solid rgb(234, 234, 234); background-color: rgb(248, 248,
248); border-radius: 3px 3px 3px 3px; display: inline;">m
-> r</code>.</p>
</div>
</body>
</html>