[Haskell-beginners] the equivalent of OO class data and methods

Yitzchak Gale gale at sefer.org
Thu Apr 2 14:35:26 EDT 2009


Michael Mossey wrote:
> For example, if I want to create LayoutItem and name its coordinates x and
> y...
> Then later I can refer to p.x and p.y.
> I can also create other classes and name *their* member variables x and y,
> with no confusion.

There are two ways to share names in Haskell.

One way, which is most similar to the OO approach, is to use
encapsulation. Haskell uses modules for encapsulation
and namespace control. However, GHC currently requires
each module to reside in a separate source file (even though
that is not required by the standard).

When you use this method, you need to use dotted names
to qualify them, as in your OO example. If only one version
of a name is used in a given module, you can choose to
import that name unqualified into the namespace of that
module.

The other approach is using the class system:

class Coordinates a where
  x :: a -> Int
  y :: a -> Int

data LayoutItem = LayoutItem { layoutItemX, layoutItemY :: Int }

instance Coordinates LayoutItem where
  x = layoutItemX
  y = layoutItemY

data Notehead = Notehead { noteheadItemX, noteheadItemY :: Int }

instance Coordinates Notehead where
  x = NoteheadX
  y = NoteheadY

Note that using this approach, the types of x and y always need
to have exactly the same shape: a -> Int, where a is the type for
which you are declaring the class instance. You can't use Int
for one type and Float for another, for example.

You can get around that restriction using Haskell extensions such
as type families, or multiparameter classes and functional
dependencies.

With the approach, you do not qualify the names. You just re-use
the names, and the type checker figures out what you mean from
the context. In case of ambiguity, you use explicit type signatures
to clarify the situation.

Hope this helps,
Yitz


More information about the Beginners mailing list