<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Sep 13, 2013 at 9:18 AM, Mario Blažević <span dir="ltr">&lt;<a href="mailto:blamario@acanac.net" target="_blank">blamario@acanac.net</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">


On 09/13/13 01:51, Michael Snoyman wrote:<div class="im"><br>
On Fri, Sep 13, 2013 at 5:38 AM, Mario Blažević &lt;<a href="mailto:blamario@acanac.net" target="_blank">blamario@acanac.net</a> &lt;mailto:<a href="mailto:blamario@acanac.net" target="_blank">blamario@acanac.net</a>&gt;&gt; wrote:<br>


<br>
    On 09/11/13 19:37, John Lato wrote:<br>
<br>
<br></div><div class="im">
        3.  I&#39;m not entirely sure that the length* functions belong<br>
        here.  I<br>
        understand why, and I think it&#39;s sensible reasoning, and I<br>
        don&#39;t have a<br>
        good argument against it, but I just don&#39;t like it.  With<br>
        those, and<br>
        mapM_-like functions, it seems that the foldable class is<br>
        halfway to<br>
        being another monolithic ListLike.  But I don&#39;t have any<br>
        better ideas<br>
        either.<br>
<br>
<br>
            If monolithic classes bother you, my monoid-subclasses<br>
    package manages to break down the functionality into several<br>
    classes. One big difference is that everything is based off Monoid<br>
    rather than Foldable, and that has some big effects on the interface.<br>
<br>
<br>
<br>
I&#39;d point out what I&#39;d consider a bigger difference: the type signatures have changed in a significant way. With MonoFoldable, folding on a ByteString would be:<br>
<br>
    (Word8 -&gt; b -&gt; b) -&gt; b -&gt; ByteString -&gt; b<br>
<br>
With monoid-subclasses, you get:<br>
<br>
    (ByteString -&gt; b -&gt; b) -&gt; b -&gt; ByteString -&gt; b<br>
<br>
There&#39;s certainly a performance issue to discuss, but I&#39;m more worried about semantics. Word8 tells me something very specific: I have one, and precisely one, octet. ByteString tells me I have anywhere from 0 to 2^32 or 2^64  octets. Yes, we know from context that it will always be of size one, but the type system can&#39;t enforce that invariant.<br>


</div></blockquote>
<br>
    All true, but we can also use this generalization to our advantage. For example, the same monoid-subclasses package provides ByteStringUTF8, a newtype wrapper around ByteString. It behaves the same as the plain ByteString except its atomic factors are not of size 1, instead it folds on UTF-8 encoded character boundaries. You can&#39;t represent that in Haskell&#39;s type system.<div class="">

<div class="h5"><br>
<br></div></div></blockquote><div><br></div><div>I can think of two different ways of achieving this approach with MonoFoldable instead: by setting `Element` to either `Char` or `ByteStringUTF8`. The two approaches would look like:</div>

<div><br></div><div><div>newtype ByteStringUTF8A = ByteStringUTF8A S.ByteString</div><div>type instance Element ByteStringUTF8A = Char</div><div>instance MonoFoldable ByteStringUTF8A where</div><div>    ofoldr f b (ByteStringUTF8A bs) = ofoldr f b (decodeUtf8 bs)</div>

<div>    ofoldl&#39; = undefined</div><div><br></div><div>newtype ByteStringUTF8B = ByteStringUTF8B S.ByteString</div><div>type instance Element ByteStringUTF8B = ByteStringUTF8B</div><div>instance MonoFoldable ByteStringUTF8B where</div>

<div>    ofoldr f b (ByteStringUTF8B bs) = ofoldr (f . ByteStringUTF8B . encodeUtf8 . T.singleton) b (decodeUtf8 bs)</div><div>    ofoldl&#39; = undefined</div></div><div><br></div><div>I&#39;d personally prefer the first approach, as that gives the right guarantees at the type level: each time the function is called, it will be provided with precisely one character. I believe the second approach provides the same behavior as monoid-subclasses does right now.</div>

<div><br></div><div>Michael</div></div></div></div>