<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <br>
    <div class="moz-cite-prefix">On 07/25/2013 11:22 AM, Edward Kmett
      wrote:<br>
    </div>
    <blockquote
cite="mid:CAJumaK87oXVKOFR8r4B5rg2k7Wjvgiyr7Gc6jjPJieAkY7aknA@mail.gmail.com"
      type="cite">
      <div>In your case here mapM_ f would turn into Foldable.<span
          class="hs-varid">foldr</span> <span class="hs-layout"
          style="color:red">(</span><span class="hs-layout"
          style="color:red">(</span><span class="hs-varop">&gt;&gt;</span><span
          class="hs-layout" style="color:red">)</span> <span
          class="hs-varop">.</span> <span class="hs-varid">f</span><span
          class="hs-layout" style="color:red">)</span> <span
          class="hs-layout" style="color:red">(</span><span
          class="hs-varid">return</span> <span class="hs-conid">()</span><span
          class="hs-layout" style="color:red">) </span>if it were to
        inline (which it isn't set up to do) rather than into
        Control.Monad.mapM_. Once it became Foldable.foldr it'd get
        stuck on the way to becoming GHC.List.foldr and then to fusion
        by the fact that we don't inline the members of the Foldable []
        instance.</div>
      <div><br>
      </div>
      <div>
        <div>As an aside, it is interesting that in <a
            moz-do-not-send="true"
href="http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/Data-Traversable.html#Traversable">http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/Data-Traversable.html#Traversable</a> the
          traverse is INLINE'd but not the mapM, though it is irrelevant
          to your issue here, it is another thing that would likely be
          impacted.</div>
      </div>
      <div><br>
      </div>
      <div>So there appears to be at least two obstacles in the way of
        this fusing away properly, and yet another in the way of normal
        mapM fusing.</div>
      <div><br>
      </div>
      <div>Some of this could be mitigated by rephrasing the foldr/build
        rule directly in terms of Foldable.foldr where it'd only
        typecheck if applied to a [] anyways, but it does look like a
        serious look will have to be made at what gets inlined as we
        proceed to investigate how to get this to work right.</div>
      <div><br>
      </div>
    </blockquote>
    <br>
    If I understand what you are saying then I tried something similar
    to this, too, where I provided a rewrite rule that would only
    rewrite if it type-checked:<br>
    <br>
    _each :: (Monad m) =&gt; [a] -&gt; Producer a m ()<br>
    _each = Prelude.mapM_ yield<br>
    <br>
    {-# RULES "_each" each = _each #-}<br>
    <br>
    If I do this GHC spits out a big internal debug message when I
    compile it.  It does compile successfully, but it doesn't work and
    that rewrite rule does not fire.<br>
    <br>
    I think the most reliable way will just be making sure that there is
    a clear chain of INLINEs all the way down.<br>
    <br>
    <blockquote
cite="mid:CAJumaK87oXVKOFR8r4B5rg2k7Wjvgiyr7Gc6jjPJieAkY7aknA@mail.gmail.com"
      type="cite">
      <div>-Edward</div>
      <div><br>
        <div class="gmail_quote">On Thu, Jul 25, 2013 at 1:55 PM,
          Gabriel Gonzalez <span dir="ltr">&lt;<a
              moz-do-not-send="true" href="mailto:gabriel439@gmail.com"
              target="_blank">gabriel439@gmail.com</a>&gt;</span> wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">
            <div text="#000000" bgcolor="#FFFFFF">
              <div class="im"> <br>
                <div>On 07/25/2013 10:41 AM, Edward Kmett wrote:<br>
                </div>
                <blockquote type="cite">One of the open concerns about
                  it is definitely ensuring that we get the fusion
                  opportunities we can.
                  <div><br>
                  </div>
                  <div>If you put an INLINE pragma on your Foldable
                    version of each do the fusion rules fire after it
                    gets inlined into a call site that uses it as a
                    list?<br>
                    <div><br>
                    </div>
                  </div>
                </blockquote>
                <br>
              </div>
              I tried both INLINE and INLINABLE and neither causes the
              fusion rules to fire.  I also tried:<br>
              <br>
              * adding an orphan SPECIALIZE rule for
              `Data.Foldable.mapM_` in the module where I defined `each`<br>
              <br>
              * Specializing the type of `each` to consume lists, but
              still using the `Foldable` `mapM_`<br>
              <br>
              * Defining a new copy of `each` (using the `Foldable`
              version) in the same module as the code that uses it,
              specializing the type signature to lists, and trying out
              INLINE/INLINABLE or no pragma.<br>
              <br>
              None of those causes the rule to fire, either.
              <div class="im"><br>
                <br>
                <blockquote type="cite">
                  <div>
                    <div>-Edward<br>
                      <br>
                      <div class="gmail_quote">On Thu, Jul 25, 2013 at
                        1:22 PM, Gabriel Gonzalez <span dir="ltr">&lt;<a
                            moz-do-not-send="true"
                            href="mailto:gabriel439@gmail.com"
                            target="_blank">gabriel439@gmail.com</a>&gt;</span>
                        wrote:<br>
                        <blockquote class="gmail_quote" style="margin:0
                          0 0 .8ex;border-left:1px #ccc
                          solid;padding-left:1ex">I'm now in favor of
                          the `Data.Foldable` proposal, but I just
                          wanted to mention that the proposal needs to
                          include some extra pragma work to ensure that
                          build/foldr optimizations fire.  I was just
                          experimenting with the following combinator
                          for `pipes` trying out the following two
                          versions:<br>
                          <br>
                              each :: (Monad m) =&gt; [a] -&gt; Producer
                          a m ()<br>
                              each = mapM yield<br>
                          <br>
                              each :: (Monad m, Foldable f) =&gt; f a
                          -&gt; Producer a m ()<br>
                              each = Data.Foldable.mapM yield<br>
                          <br>
                          When I do a pure `pipes`-based fold over both
                          `Producers`s, the version specialized to lists
                          triggers a firing of the build/foldr fusion
                          rule and runs about 20% faster.  The true
                          improvement for `mapM` by itself is probably
                          even greater than that because I haven't
                          optimized the folding code yet.  The latter
                          version does not trigger the rule firing.
                           Either way I'm going to include the latter
                          `Foldable` version but I just wanted to
                          mention this because I remember people were
                          asking if this would impact fusion or not.<br>
                          <br>
_______________________________________________<br>
                          Libraries mailing list<br>
                          <a moz-do-not-send="true"
                            href="mailto:Libraries@haskell.org"
                            target="_blank">Libraries@haskell.org</a><br>
                          <a moz-do-not-send="true"
                            href="http://www.haskell.org/mailman/listinfo/libraries"
                            target="_blank">http://www.haskell.org/mailman/listinfo/libraries</a><br>
                        </blockquote>
                      </div>
                      <br>
                    </div>
                  </div>
                </blockquote>
                <br>
              </div>
            </div>
          </blockquote>
        </div>
        <br>
      </div>
    </blockquote>
    <br>
  </body>
</html>