
On 5/19/11 5:51 PM, Antoine Latter wrote:
On Thu, May 19, 2011 at 3:06 PM, Simon Meier
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/B...) 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