
Francesco Bochicchio wrote:
me too :-)
Again, StaffItem and TextItem resemble derived classes in OO.
To me, they are more close to C union : a data type than can alternatively have different structures, In your example, LayoutItem is a type name, while StaffItem and TextItem are constructor, that is functions. Saying that a function specializes a type is a bit of a stretch, I think ...
Nevertheless, they can sometime be used to accomplish the same goal : where in OO you define an abstact class and then specialize with concrete classes to model a classification, in haskell you can define a data type with alternate constructors.
I think that data types with alternate constructores are called algebraic data types in haskellese, but I'm not sure of that ...
Here's what I've learned from my investigations, but I welcome any clarifications. There are a few ways they don't resemble constructors in OO, or unions in C. They are "constructors", but also "take apart" the item in pattern matching. myfunc (StaffItem pos dimension) = ... myfunc (TextItem pos dimension) = ... You can also hide the constructors when you export a module. I could export LayoutItem but not StaffItem and TextItem, meaning that other code would see LayoutItem as a kind of abstract base class. When you name a field in each constructor (the same name), you can access that field on any LayoutItem without knowing its constructor using the accessor function for that field. This looks a lot like an abstract base class. data LayoutItem = TextItem { myField :: Int } | StaffItem { myField :: Int } x1 = TextItem { myField = 3 } x2 = STaffItem { myField = 4 } y1 = myField x1 y2 = myField x2 When I tried to make TextItem and StaffItem instances of a class, I got an error. They aren't really types. Only LayoutItem is the type. instance Eq TextItem where ... ---> ERROR! instance Eq StaffItem where ... ---> ERROR! instance Eq LayoutItem where... ---> ok Right now I'm just confused by how to translate an exising OO design. I'm porting a partially complete Python program to Haskell. There are many options. For instance I could set up a class called LayoutClass, make TextItem and StaffItem their own classes and make them instances of the class. -- Note: Now I can no longer have any overlapping field names data TextItem = TextItem { tField1, tField2 :: Int } data StaffItem = StaffItem { sField1, sField3 :: Int } class LayoutClass a where access1 :: a -> Int instance LayoutClass TextItem where access1 (TextItem t) = tField1 t instance LayoutClass StaffItem where access1 (StaffItem s ) = sField1 s Or put everything in its own module and use qualified names. Probably the best choice for future considerations.