[Haskell-beginners] accessor function scope

John Dorsey haskell at colquitt.org
Tue Apr 7 09:00:54 EDT 2009


> I've noticed that if I declare two types like this
>
> data Thing1 = Thing1 { itemPos :: Int }
> data Thing2 = Thing2 { itemPos :: Int }
>
> then I get the error "Multiple declarations of Main.itemPos"

Here's something to consider.  What's the type of itemPos?  In the above
code, it can't be

  itemPos :: Thing1 -> Int

because you want to be able to apply it to a Thing2.  I suppose the
compiler could, behind the scenes, create a typeclass like this:

  class ItemPosAble a where
    itemPos :: a -> Int
  instance ItemPosAble Thing1 where
    itemPos (Thing1 x) = x
  instance ItemPosAble Thing2 where
    itemPos (Thing2 x) = x

Then itemPos has type

  itemPos :: (ItemPosAble t) => t -> Int

Maybe that would work, modulo my typos.  But it's messy, and it gets
messier if itemPos doesn't have the same return type in all examples.  It
probably makes it harder to produce clear error messages when something
goes wrong.  There are probably other issues I haven't seen yet.

At any rate, just disallowing this kind of "overloading" of the accessor
function is simple, and works.  As you point out later, you can reuse
the name by separating namespaces using modules.

> data LayoutItem = StaffItem { itemPos :: Pos,
>                               itemDim :: Dimension }
>                 | TextItem { itemPos :: Pos,
>                              itemDim :: Dimension }

Here the type of itemPos is clearly just

  itemPos :: LayoutItem -> Pos

No problem.  Behind the scenes, the compiler is defining it as something
like

  itemPos (StaffItem x _) = x
  itemPos (TextItem  x _) = x

> This seems to define itemPos in a way that can sense whether it's dealing 
> with a StaffItem-type LayoutItem or a TextItem-type LayoutItem. I don't 

You're right that there's enough information to figure it out in
this example code, but the type inference in Haskell doesn't do this
kind of ad-hockery.

> know if this would be considered an overloaded operator. However, it does 
> resemble derived class in OO.

It's not a bad exercise to compare Haskell to what you already know, but
expect it to break down before long.  Clear and idiomatic functional
design will generally look pretty different from clear and idiomatic OO
design.  That said, you can do OO stuff in Haskell; it's just not very fun,
and generally not needed.

> For that matter, I don't know what the term is for a "StaffItem-type 
> LayoutItem". The type is clearly LayoutItem. "StaffItem" is the 
> constructor. How do you refer to the concept of a LayoutItem constructed 
> via a StaffItem?

You can just call it "a StaffItem", I guess.  I don't know if there's a
common term.  But you're right that it's type is LayoutItem.

Regards,
John



More information about the Beginners mailing list