<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hello,<div class=""><br class=""></div><div class="">Independently of a blog post I just noticed tonight on reddit, <a href="http://www.snoyman.com/blog/2017/01/follow-up-mapm" class="">http://www.snoyman.com/blog/2017/01/follow-up-mapm</a> I observed a stack overflow in some code I was working with due to a recursive call inside the function argument of for_</div><div class=""><br class=""></div><div class="">The code was a more complicated version of:</div><div class=""><br class=""></div><div class=""><font face="Courier New" class="">go = for_ someMaybe $ \m -> m >> go</font></div><div class=""><br class=""></div><div class="">It was wrong in thinking that this could be efficient because there’s an extra operation to set the result to a (). I thought I might try working around this with the following code.</div><div class=""><br class=""></div><div class=""><div class=""><font face="Courier New" class="">for__ :: (Applicative f, Foldable t) => t a -> (a -> f ()) -> f ()</font></div><div class=""><font face="Courier New" class="">for__ xs f = unApp (foldMap (coerce f) xs)</font></div><div class=""><br class=""></div></div><div class=""><div class=""><font face="Courier New" class="">newtype App f = App { unApp :: f () }</font></div><div class=""><font face="Courier New" class=""><br class=""></font></div><div class=""><font face="Courier New" class="">instance Applicative f => Monoid (App f) where</font></div><div class=""><font face="Courier New" class="">  mempty                  = App (pure ())</font></div><div class=""><font face="Courier New" class="">  mappend (App x) (App y) = App (x *> y)</font></div></div><div class=""><br class=""></div><div class="">Unfortunately the instance for Foldable for Maybe does not provide an implementation of foldMap, it only provides foldl and foldr. This means that the derived foldMap implementation attempts to mappend an extra mempty because the default implementation of foldMap is</div><div class=""><br class=""></div><div class=""><pre style="font-variant-ligatures: normal; orphans: 2; widows: 2;" class=""><font face="Courier New" class=""> <a name="local-8214565720323889834" class=""></a><a href="http://hackage.haskell.org/package/base-4.9.1.0/docs/src/Data.Foldable.html#foldMap" class="" style="text-decoration: none; border-bottom: 1px solid rgb(238, 232, 213);"><span class="hs-identifier" style="color: rgb(7, 54, 66);">foldMap</span></a> <a name="local-6989586621679114983" class=""></a><a href="http://hackage.haskell.org/package/base-4.9.1.0/docs/src/Data.Foldable.html#local-6989586621679114983" class="" style="text-decoration: none; border-bottom: 1px solid rgb(238, 232, 213);"><span class="hs-identifier" style="color: rgb(7, 54, 66);">f</span></a> <span class="hs-glyph" style="color: rgb(220, 50, 47);">=</span> <a href="http://hackage.haskell.org/package/base-4.9.1.0/docs/src/Data.Foldable.html#foldr" class="" style="text-decoration: none; border-bottom: 1px solid rgb(238, 232, 213);"><span class="hs-identifier hs-var" style="color: rgb(7, 54, 66);">foldr</span></a> <span class="hs-special" style="color: rgb(220, 50, 47);">(</span><a href="http://hackage.haskell.org/package/base-4.9.1.0/docs/src/GHC.Base.html#mappend" class="" style="text-decoration: none; border-bottom: 1px solid rgb(238, 232, 213);"><span class="hs-identifier hs-var" style="color: rgb(7, 54, 66);">mappend</span></a> <a href="http://hackage.haskell.org/package/base-4.9.1.0/docs/src/GHC.Base.html#." class="" style="text-decoration: none; border-bottom: 1px solid rgb(238, 232, 213);"><span class="hs-operator hs-var" style="color: rgb(211, 54, 130);">.</span></a> <a href="http://hackage.haskell.org/package/base-4.9.1.0/docs/src/Data.Foldable.html#local-6989586621679114983" class="" style="text-decoration: none; border-bottom: 1px solid rgb(238, 232, 213);"><span class="hs-identifier hs-var" style="color: rgb(7, 54, 66);">f</span></a><span class="hs-special" style="color: rgb(220, 50, 47);">)</span> <a href="http://hackage.haskell.org/package/base-4.9.1.0/docs/src/GHC.Base.html#mempty" class="" style="text-decoration: none; border-bottom: 1px solid rgb(238, 232, 213);"><span class="hs-identifier hs-var" style="color: rgb(7, 54, 66);">mempty</span></a></font></pre><div class=""><br class=""></div></div><div class="">With an explicit implementation of foldMap for the Maybe type (and maybe there are others that we’ve missed, for__ above can be stack efficient.</div><div class=""><br class=""></div><div class=""><div class="">So I propose that we add an explicit implementation of foldMap to the Foldable Maybe instance</div><div class=""><br class=""></div><div class=""><font face="Courier New" class="">  foldMap _ Nothing  = mempty</font></div><div class=""><font face="Courier New" class="">  foldMap f (Just x) = f x</font></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Best regards,</div></div><div class="">Eric Mertens</div></body></html>