<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">>></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) => [a] -> 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"><<a
moz-do-not-send="true" href="mailto:gabriel439@gmail.com"
target="_blank">gabriel439@gmail.com</a>></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"><<a
moz-do-not-send="true"
href="mailto:gabriel439@gmail.com"
target="_blank">gabriel439@gmail.com</a>></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) => [a] -> Producer
a m ()<br>
each = mapM yield<br>
<br>
each :: (Monad m, Foldable f) => f a
-> 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>