<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"><<a href="mailto:blamario@acanac.net" target="_blank">blamario@acanac.net</a>></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ć <<a href="mailto:blamario@acanac.net" target="_blank">blamario@acanac.net</a> <mailto:<a href="mailto:blamario@acanac.net" target="_blank">blamario@acanac.net</a>>> wrote:<br>
<br>
On 09/11/13 19:37, John Lato wrote:<br>
<br>
<br></div><div class="im">
3. I'm not entirely sure that the length* functions belong<br>
here. I<br>
understand why, and I think it's sensible reasoning, and I<br>
don't have a<br>
good argument against it, but I just don'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'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'd point out what I'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 -> b -> b) -> b -> ByteString -> b<br>
<br>
With monoid-subclasses, you get:<br>
<br>
(ByteString -> b -> b) -> b -> ByteString -> b<br>
<br>
There's certainly a performance issue to discuss, but I'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'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't represent that in Haskell'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' = 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' = undefined</div></div><div><br></div><div>I'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>