<div dir="ltr"><div>Hi,</div><div><br></div>I have this code snippet for the bind implementation of a Monad:<div><br></div><div><div>    AsyncT m >>= f = AsyncT $ \_ stp yld -></div><div>        let run x = (runAsyncT x) Nothing stp yld</div><div>            yield a _ Nothing  = run $ f a</div><div>            yield a _ (Just r) = run $ f a <> (r >>= f)</div><div>        in m Nothing stp yield</div></div><div><br></div><div>I want to have multiple versions of this implementation parameterized by a function, like this:</div><div><br></div><div><div>bindWith k (AsyncT m) f = AsyncT $ \_ stp yld -></div><div>    let run x = (runAsyncT x) Nothing stp yld</div><div>        yield a _ Nothing  = run $ f a</div><div>        yield a _ (Just r) = run $ f a `k` (bindWith k r f)</div><div>    in m Nothing stp yield</div></div><div><br></div><div>And then the bind function becomes:</div><div><br></div><div>







<p class="gmail-p1"><span class="gmail-s1">(</span><span class="gmail-s2">>>=</span><span class="gmail-s1">)</span><span class="gmail-s3"> </span><span class="gmail-s2">=</span><span class="gmail-s3"> </span><span class="gmail-s3">bindWith </span><span class="gmail-s5">(</span><span class="gmail-s2"><></span><span class="gmail-s5">)</span></p></div><div>But this leads to a performance degradation of more than 10%. inlining does not help, I tried INLINE pragma as well as the "inline" GHC builtin. I thought this should be a more or less straightforward replacement making the second version equivalent to the first one. But apparently there is something going on here that makes it perform worse. </div><div><br></div><div>I did not look at the core, stg or asm yet. Hoping someone can quickly comment on it. Any ideas why is it so? Can this be worked around somehow?</div><div><br></div><div>Thanks,</div><div>Harendra</div></div>