[Haskell-beginners] accessor function scope

Michael Mossey mpm at alumni.caltech.edu
Tue Apr 7 05:47:32 EDT 2009



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.



More information about the Beginners mailing list