[Haskell-cafe] blaze-builder and FlexibleInstances in code that aims to become part of the Haskell platform
wren ng thornton
wren at freegeek.org
Fri May 20 02:00:00 CEST 2011
On 5/19/11 5:51 PM, Antoine Latter wrote:
> On Thu, May 19, 2011 at 3:06 PM, Simon Meier<iridcode at gmail.com> wrote:
>
>> The core problem that drove me towards this solution is the abundance
>> of different IntX and WordX types. Each of them requiring a separate
>> Write for big-endian, little-endian, host-endian, lower-case-hex, and
>> uper-case-hex encodings; i.e., currently, there are
>>
>> int8BE :: Write Int8
>> int16BE :: Write Int16
>> int32BE :: Write Int32
>> ...
>> hexLowerInt8 :: Write Int8
>> ...
>>
>> and so on. As you can see
>> (http://hackage.haskell.org/packages/archive/blaze-builder/0.3.0.1/doc/html/Blaze-ByteString-Builder-Word.html)
>> this approach clutters the public API quite a bit. Hence, I'm thinking
>> of using a separate type-class for each encoding; i.e.,
It seems to me that a better way of handling this would be to explicitly
define an ADT (or type-level equivalent) for naming the different format
options. That is, something like this:
data Endianness = BE | LE | HE
data Radix = Binary | Octal | Decimal | Hexadecimal
...
data WIFormat = WIFormat
{ endianness :: {-# UNPACK #-} !Endianness
, radix :: {-# UNPACK #-} !Radix
...}
class WriteWI a where
writeWI :: WIFormat -> Write a
If you're sure that you can get rid of the typeclass overhead, then you
should be able to get rid of the case analysis on the ADT as well (by
making sure to always use writeWI fully saturated). But this way, you
only need to deal with one class and it's obvious how to extend it (as
opposed to your newtype solution where it's not clear whether the order
of newtype wrapping matters, etc).
Of course, I'm not advocating that specific ADT for encoding format
types. For example, it's only in decimal format where there's any
difference between Word* and Int* types, since the signedness never
shows up explicitly in binary, oct, or hex representations. There's also
the issues you've mentioned about whether hex is upper case or lower
case, whether there's a leading sigil like 0 or 0o for oct, or 0x, \x,
U+,... for hex. And so on. So you'll need to figure out what all the
formats are you want to offer, but it should be straightforward to come
up with an ADT like the one above, and then you can just case match on
it to choose the specific format.
As for the class, if you run into too much type ambiguity and want to
avoid the need for type signatures, then you can add an unused argument
of type @a@ as is common in other core libraries needing to be H98
compliant.
--
Live well,
~wren
More information about the Haskell-Cafe
mailing list