[Haskell-cafe] Re: self-referential data

Michael Karcher usenet at mkarcher.dialup.fu-berlin.de
Mon Aug 11 12:02:08 EDT 2008

brian <brianchina60221 at gmail.com> wrote:
> > 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
 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.

  Michael Karcher

More information about the Haskell-Cafe mailing list