
Patrick Browne wrote:
Hi, I am trying to understand the data type declaration below. What is the relation between class C3 and the data type Address below? Where is such a technique used?
OK, let's see what we can come up with...
module A where data Person = Person String Integer deriving Show data Employee = Employee String Integer deriving Show
Person and Employee are identical types, just with different names.
class C1 c1 where age :: c1 -> Integer
The "age" function works for any type declared to be an instance of C1.
instance C1 Person where age(Person "P1" 1) = 1
instance C1 Employee where age(Employee "E1" 1) = 1
Person and Employee are both declared to be instances of C1. Incidentally, those declarations look *very* dubious. What the first one says, for example, is that if a person is called "P1" and their age is 1, then return 1. If the name is not "P1" or the age is not 1, crash.
class C1 c2 => C2 c2 where name :: c2 -> String
The "name" function works for any type declared to be an instance of C2. Any such type must also be an instance of C1.
instance C2 Person where name(Person "P2" 1) = "P2"
instance C2 Employee where name(Employee "E2" 1) = "E2"
Person and Employee are both instances of C2 (which is allowed, since they are already instances of C1). Again, the instance declarations look highly dubious.
class C2 c3 => C3 c3 a where address :: c3 -> a
This is not valid in Haskell '98. This is actually a type system extension known as "multi-parameter type classes", which do not even vaguely correspond to anything in normal OOP. (Except for being very slightly similar to generics, perhaps.) Here C3 is a relation *between* two types (type "c3" and type "a"). For any so-related types, the "address" fucntion can map one type to the other. (Presumably by returning the contents of an address field...) This is a very odd way to define such an action.
instance C3 Person String where
The types Person and String are related by C3 as described above. However, calling "address" will crash immediately (since no implementation is supplied).
-- ** What are the semantics or purpose of this construct. -- ** Is the type declared in the context of a class. data C3 c3 a => Address c3 a = Address c3 a
This defines a new type named "Address". The type has two type parameters ("c3" and "a"), and a value of this type has two fields. In other words, if you say "Address Rock Stone", then an Address value has two fields, the first one of type Rock, the second of type Stone. Also, the type parameters are required to be related by C3. So unless you write "instance C3 Rock Stone", you cannot say "Address Rock Stone". It would be a type error. However, since "instance C3 Person String" exists above, you may say "Address Person String".
instance C3 Person (Address String String) where
This says that the type "Person" and the type "Address String String" are related by C3 as well - which is amusing, given that "Address String String" is a type error due to the fact that we don't have "instance C3 String String"... In short, this big tangle of code shouldn't even compile, and if it does, I have no clue what in the name of God it actually does. It appears to have been written by somebody who has no idea what they're doing. If you want to know what a specific language construct does, or why you'd use it, or which way you'd attack a specific problem, I (and everybody else here) can try to offer some explanation. But the code you're showing me doesn't really make any sense.