
brian
What's wrong with just using 'String' as the Map key? It seems wrong. Yeah, it's just a String, but we're being all abstract because that's better practice. It happens that when you parse bencoded data, the length of the string is given. Maybe I want to store that in BString, too.
So, why not just type BString_ = String data BValue = BString BString_ | BDictionary (Map BString_ BValue) you always can change BString_ to obtain a different representation for a) String values in you BValues and b) keys in your BDictionary at the same time. The "BString" data constructor means "This BValue is something called BString, oh, and, by the way, there is a string stored here". It does not mean at all that "BString" somehow represents the String type. So it really makes no sense as parameter to the Map. Just imagine, what would happen, if the BString constructor has more than one parameter. What should be the key for the map in that case? If you want to add a layer of abstraction, use a newtype instead of the type alias. But that means, standard string functions don't work on BString_ anymore. On the other hand, you are right that there is no really simple sum type notation in haskell, like "a BValue(type) is either a BString(type), a BInteger(type) or a BDictionary(type)", but you have to say the more verbose variant: "a BValue(type) is constructed in on of the following ways: a mark called BString(data constructor) accompanied by a String; a mark called BInteger(data constructor) accompanied by an Integer or a mark called BDictionary(data constructor) accompanied by a Map." These marks are surely no types. Your intuition seems more like what the other poster also suggests: data BString = BString String data BInteger = BInteger Integer data BDictionary = BDictionary (Map BString BValue) data BValue = BVString BString | BVInteger BInteger | BVDictionary BDictionary There just is no way around the data constructors (called BV...), even if they seem kind-of redundant. You might want to use newtype instead of data in the first three definitions to reduce runtime overhead, or even use type aliases for added convenience in trade for abstraction. Regards, Michael Karcher