
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