<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div style="" data-md-original="&lt;div
      class=&quot;moz-cite-prefix&quot;&gt;&lt;br&gt;&lt;br&gt;Dne
      06/03/2013 09:11 PM, Henning Thielemann
      napsal(a):&lt;br&gt;&lt;/div&gt;&lt;blockquote
      cite=&quot;mid:alpine.DEB.2.00.1306032109530.12856@anubis.informatik.uni-halle.de&quot;
      type=&quot;cite&quot;&gt;
      &lt;br&gt;On Mon, 3 Jun 2013, Edward Kmett wrote:
      &lt;br&gt;
      &lt;br&gt;&lt;blockquote type=&quot;cite&quot;&gt;The first option
      is
      &lt;br&gt;
      &lt;br&gt;class Monad m =&amp;gt; MonadRef r m | m -&amp;gt; r
      where
      &lt;br&gt;&amp;nbsp; newRef :: a -&amp;gt; m (r a)
      &lt;br&gt;&amp;nbsp; ...
      &lt;br&gt;
      &lt;br&gt;This has the benefit of using quite portable extensions.
      &lt;br&gt;
      &lt;br&gt;The second option is
      &lt;br&gt;
      &lt;br&gt;class Monad m =&amp;gt; MonadRef m where&amp;nbsp; type
      Ref m :: * -&amp;gt; *
      &lt;br&gt;&amp;nbsp; newRef :: a -&amp;gt; m (Ref m a)
      &lt;br&gt;&amp;nbsp;
      &lt;br&gt;This takes us into GHC specific territory, by using type
      families, but avoids polluting every type that uses
      &lt;br&gt;one with an extra 'ref' param. I use this variant in my
      as-yet-unreleased 'revisions' package.
      &lt;br&gt;
      &lt;br&gt;Both of these have the benefit that they can work with
      transformers, but they carry the limitation that you
      &lt;br&gt;can't have multiple reference types for the same monad.
      e.g. you can't use the same combinators for both
      &lt;br&gt;IORefs and, say, MVars or TVars within the same monad.
      This is arguably not so much a problem as they have
      &lt;br&gt;very different operational semantics!
      &lt;br&gt;&lt;/blockquote&gt;
      &lt;br&gt;I thought the functional dependency should be the other
      way round: From the reference type to the monad where it lives in.
      &lt;br&gt;
      &lt;/blockquote&gt;&lt;br&gt;For monads, it's (AFAIK) always this
      way, because `m` is always in the result, but not necessarily the
      other type. Let's consider&lt;br&gt;```haskell&lt;br&gt;readRef ::
      r a -&amp;gt; m a&lt;br&gt;```&lt;br&gt;In order to type-check `x`
      in `readRef x`, we need to determine `r a` from `m a`, so the
      dependency must be `m -&amp;gt; r`.&lt;br&gt;"
      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 =&gt; MonadRef r m | m -&gt; r where
            <br>
              newRef :: a -&gt; 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 =&gt; MonadRef m where  type Ref m :: * -&gt;
            *
            <br>
              newRef :: a -&gt; 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 -&gt; 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
          -&gt; r</code>.</p>
    </div>
  </body>
</html>