
On Mon, Oct 17, 2011 at 12:14 PM, Bas van Dijk
On 17 October 2011 10:18, Christian Maeder
wrote: I think the cleanest solution (just from a theoretical point of view) is to use a newtype for your byte strings.
- it should have the same performance - allows to make ByteString really abstract when hiding the newtype constructor
But what would a newtype ByteString = ByteString (Vector Word8) abstract over? What's there to hide? Vectors are already abstract so users can't mess with their internals.
- is portable and supplies control over all other instances (not just Show)
What other instances (besides Show) should have different semantics than those of Vector?
I'm not sure if one could make really bad thinks to your ByteString by using the Vector interface, but one would want to disallow vector operations just for compatible with other byte strings.
My idea is that when vector-bytestring is as fast as bytestring, it can replace it. When that happens it doesn't matter if users use the vector interface. I would even recommend it over using the bytestring interface so that bytestring can eventually be deprecated in favor of vector.
+1. I'm in favor of using the OverlappingInstances/no newtype and specialized Show instance. I think that, if there was *ever* a case where OverlappingInstances was a good fit, it's this one. We're talking about a single module exporting both the base and overlapped instance, so which instance gets used should be completely decidable. (Unless of course someone defines an orphan instance elsewhere, but that's a different issue IMO.) And even in a worst-case-scenario where somehow we get the wrong instance, we're only talking about output used as a debugging aid, so the damage is minimal. Also, aren't there a few documented cases where newtypes prevent certain GHC rewrite rules from firing? I don't see any strong argument to avoid what appears to be the simplest and most straight-forward solution to the problem at hand. Michael