Question

I have the following for an HTML font tag:

data Color = HexColor Int | RGBColor Int Int Int | ColorString String deriving Show
data FontAttribute = Size Int | Face String | FontColor Color deriving Show
data Font = Font [FontAttribute] deriving Show

I construct one like so:

Font [Size 23,Face "Arial",Color (RGBColor 240 23 43)]

My concern is that the FontColor data/value constructor which has type FontAttribute requires a Color type as an argument. This means that Color is a generic type attribute for any kind of tag, and a specific tag has a specific subset of attributes (in this case Font has FontAttribute, which can be Size, Face or FontColor). Is there a clearer way to express this, or is my implementation sound?

Was it helpful?

Solution

Color is just a type, not an attribute. There is nothing in the type system to indicate that Color has any special relationship with FontAttribute. All that happens when you define the FontAttribute data type is that it creates a constructor called FontColor which is an ordinary function with the following type signature:

FontColor :: Color -> FontAttribute

So if you declared some new type called Link:

data LinkAttrubute = LinkColor Color | ...

Then Color could be stored in a LinkAttribute, too. A constructor does not imply an exclusive relationship with only that data type. All your FontAttribute data type says is that it MIGHT contain just a Color.

Haskell has no built-in concept of attributes because it has no built-in concept of objects. HOWEVER, you can model attributes using the Lens type from the data-lens (or fclabels) package. I would link you the packages, but I'm on my phone and it is difficult.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top