<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Not sure if I’m correct on this, but wouldn’t you get space leaks in the right-strict version as well? Because the <font face="Menlo" class="">Just</font> constructor itself isn’t strict, you still build up a long chain of <font face="Menlo" class=""><></font>. In the right-lazy version, you build up a long chain of <span style="font-family: Menlo;" class="">maybe a (a<>)</span>, which is more expensive, yes, but not asymptotically. In other words, if you’ve got a space leak in the right-lazy version, you’ll also have one in the right-strict version.<div class=""><div><br class=""><blockquote type="cite" class=""><div class="">On 23 May 2018, at 14:54, Carter Schonwald <<a href="mailto:carter.schonwald@gmail.com" class="">carter.schonwald@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">yeah ... i agreed with Eric,<div class="">we almost need Lazy and Strict versions of monoid and each blows up in different ways. I definitely had epic space leaks from the lazy Maybe Monoid </div><div class=""><br class=""></div><div class="">-1 :)</div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Wed, May 23, 2018 at 11:14 AM, Eric Mertens <span dir="ltr" class=""><<a href="mailto:emertens@gmail.com" target="_blank" class="">emertens@gmail.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class=""><div class="">Hello,</div><div class=""><br class=""></div>I think changing the strictness of this function could have potentially dramatic performance effects on a wide range of existing code. Exploring existing code to understand the exact impacts would be a huge challenge, and this is a change that would be hard to phase in.<div class=""><br class=""></div><div class="">The arbitrariness of decisions like this is part of what makes the Monoid class a mess in the first place. Attaching instances like this to otherwise generic types forces us to make arbitrary choices, which are often not documented on the instances themselves.</div><div class=""><br class=""></div><div class="">While the left-bias behavior might make sense in the case of an instance like we have for First, I don't see why it would be considered more correct in this case.</div><div class=""><br class=""></div><div class="">I'm -1 on this proposal.</div><div class=""><br class=""></div><div class="">Best regards,</div><div class="">Eric Mertens</div></div><div class="HOEnZb"><div class="h5"><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Wed, May 23, 2018 at 4:21 AM Andrew Martin <<a href="mailto:andrew.thaddeus@gmail.com" target="_blank" class="">andrew.thaddeus@gmail.com</a>> wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto" class="">I feel the the way concerning being lazy as possible and being left-strict where there is a symmetric choice to be made. This seems to be a common theme is base, although I’ve never seen it officially endorsed. I have seen Edward Kmett talk about this on reddit (contrasting it with the Monoid classes in strict-by-default languages), but I cannot find the thread.<br class=""><br class=""><div id="m_8634138045411292430m_-5047299372431800412AppleMailSignature" class="">Sent from my iPhone</div></div><div dir="auto" class=""><div class=""><br class="">On May 22, 2018, at 7:57 PM, Tikhon Jelvis <<a href="mailto:tikhon@jelv.is" target="_blank" class="">tikhon@jelv.is</a>> wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class="">I think the extra laziness makes sense here—it matches the behavior of common functions like &&. My general expectation is that functions are as lazy as they can be and, in the case of operators with two arguments, that evaluation goes left-to-right. (Again like &&.)<div class="gmail_extra"><br class=""><div class="gmail_quote">On Tue, May 22, 2018 at 4:37 PM, David Feuer <span dir="ltr" class=""><<a href="mailto:david.feuer@gmail.com" target="_blank" class="">david.feuer@gmail.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I think extra laziness here would be a bit surprising.<br class="">
<div class=""><div class="m_8634138045411292430m_-5047299372431800412h5"><br class="">
On Tue, May 22, 2018 at 5:57 PM, Donnacha Oisín Kidney<br class="">
<<a href="mailto:mail@doisinkidney.com" target="_blank" class="">mail@doisinkidney.com</a>> wrote:<br class="">
> The current semigroup instance  for Maybe looks like  this:<br class="">
><br class="">
>     instance Semigroup a => Semigroup (Maybe a) where<br class="">
>         Nothing <> b       = b<br class="">
>         a       <> Nothing = a<br class="">
>         Just a  <> Just b  = Just (a <> b)<br class="">
><br class="">
> However, it could be lazier:<br class="">
><br class="">
>     instance Semigroup a => Semigroup (Maybe a) where<br class="">
>         Nothing <> b = b<br class="">
>         Just a  <> b = Just (maybe a (a<>) b)<br class="">
><br class="">
> This causes different behaviour for Data.Semigroup.First and<br class="">
> Data.Monoid.First:<br class="">
><br class="">
>     >>>  Data.Monoid.getFirst . foldMap pure $ [1..]<br class="">
>     Just 1<br class="">
>     >>>  fmap Data.Semigroup.getFirst . Data.Semigroup.getOption . foldMap<br class="">
> (pure.pure) $ [1..]<br class="">
>     _|_<br class="">
><br class="">
> A different definition for `Option` gets back the old behaviour:<br class="">
><br class="">
>     newtype LeftOption a = LeftOption { getLeftOption :: Maybe a }<br class="">
><br class="">
>     instance Semigroup a => Semigroup (LeftOption a) where<br class="">
>       LeftOption Nothing <> ys = ys<br class="">
>       LeftOption (Just x) <> LeftOption ys = LeftOption (Just (maybe x (x<>)<br class="">
> ys))<br class="">
><br class="">
>     instance Semigroup a => Monoid (LeftOption a) where<br class="">
>       mempty = LeftOption Nothing<br class="">
>       mappend = (<>)<br class="">
><br class="">
>     >>> fmap Data.Semigroup.getFirst . getLeftOption . foldMap (LeftOption .<br class="">
> Just . Data.Semigroup.First) $ [1..]<br class="">
>     Just 1<br class="">
><br class="">
> Is there any benefit to the extra strictness? Should this be changed?<br class="">
><br class="">
> Another consideration is that the definition could equivalently be<br class="">
> right-strict, to get the desired behaviour for Last, but I think the<br class="">
> left-strict definition probably follows the conventions more.<br class="">
><br class="">
> I originally posted this to reddit<br class="">
> (<a href="https://www.reddit.com/r/haskell/comments/8lbzan/semigroup_maybe_too_strict/" rel="noreferrer" target="_blank" class="">https://www.reddit.com/r/<wbr class="">haskell/comments/8lbzan/<wbr class="">semigroup_maybe_too_strict/</a>)<br class="">
> and was encouraged to post it here.<br class="">
><br class="">
</div></div>> ______________________________<wbr class="">_________________<br class="">
> Libraries mailing list<br class="">
> <a href="mailto:Libraries@haskell.org" target="_blank" class="">Libraries@haskell.org</a><br class="">
> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank" class="">http://mail.haskell.org/cgi-<wbr class="">bin/mailman/listinfo/libraries</a><br class="">
><br class="">
______________________________<wbr class="">_________________<br class="">
Libraries mailing list<br class="">
<a href="mailto:Libraries@haskell.org" target="_blank" class="">Libraries@haskell.org</a><br class="">
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank" class="">http://mail.haskell.org/cgi-<wbr class="">bin/mailman/listinfo/libraries</a><br class="">
</blockquote></div><br class=""></div></div>
</div></blockquote><blockquote type="cite" class=""><div class=""><span class="">______________________________<wbr class="">_________________</span><br class=""><span class="">Libraries mailing list</span><br class=""><span class=""><a href="mailto:Libraries@haskell.org" target="_blank" class="">Libraries@haskell.org</a></span><br class=""><span class=""><a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" target="_blank" class="">http://mail.haskell.org/cgi-<wbr class="">bin/mailman/listinfo/libraries</a></span><br class=""></div></blockquote></div>______________________________<wbr class="">_________________<br class="">
Libraries mailing list<br class="">
<a href="mailto:Libraries@haskell.org" target="_blank" class="">Libraries@haskell.org</a><br class="">
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank" class="">http://mail.haskell.org/cgi-<wbr class="">bin/mailman/listinfo/libraries</a><br class="">
</blockquote></div>
</div></div><br class="">______________________________<wbr class="">_________________<br class="">
Libraries mailing list<br class="">
<a href="mailto:Libraries@haskell.org" class="">Libraries@haskell.org</a><br class="">
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank" class="">http://mail.haskell.org/cgi-<wbr class="">bin/mailman/listinfo/libraries</a><br class="">
<br class=""></blockquote></div><br class=""></div>
_______________________________________________<br class="">Libraries mailing list<br class=""><a href="mailto:Libraries@haskell.org" class="">Libraries@haskell.org</a><br class="">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries<br class=""></div></blockquote></div><br class=""></div></body></html>