Basic type classing question.

Hi, I've just started learning Haskell, and I must admit I'm finding it a bit hard to get my head around the typing system... If I wanted to represent Employees and Departments in a Haskell program I could use data declarations like so: data Employee = Emp ... data Department = Dept ... This seems limited in (at least) two ways: I can't dynamically add fields to an employee or department, and once I pull a field out of an instance I lose type information. What I want to be able to do is add and remove fields while the system is running, I suppose via hs-plugins, and I should be prevented from, for example, accidentally taking an employees first name and using it as a departments address. My first attempt was the following, which isn't even valid and doesn't appear to buy me much anyway. class DataContainer c class DataContainer c => DataField f c a where extract :: f -> a apply :: (a -> a -> a) -> f -> f -> f data DataContainer c => Field c a = Fld c a instance DataField Field c a where extract (Fld _ a) = a apply f (Fld c a1) (Fld _ a2) = Fld c (f a1 a2) data Employee = Emp instance DataContainer Employee data Department = Dept instance DataContainer Department type EmployeeName = Field Employee String type EmployeeAddress = Field Employee String type EmployeeIdentifier = Field Employee Integer type DepartmentAddress = Field Department String type DepartmentIdentifier = Field Department Integer ... The 'DataField instance Field' declaration gives kind errors regarding how many type arguments Field is applied to. I don't claim to understand kinds at this point. Even if it did work, apply doesn't appear to force the arguments to be of the same type, and the declared type synonyms aren't enough to prevent me getting employee names and addresses confused. Is there a correct way to express what I'm trying to do? Or is it a bad idea to start with? Thanks Karl

maybe, i completely missunderstand you. please, could you program your example in another language than haskell, one you know better? i'm not sure -- did you try to define variables instead of types? data Employee = Emp data Department = Dept translated to c++ this means sth like typedef void Employee; typedef void Department; did you want sth like ...? data Employee = Emp [(String,Either String Int)] emp1 :: Employee emp1=Emp [("Name",Left "Karl Ranseier"),("Identifier",Right 7),("Address",Left "Graveyard 13")] -marc Karl Grapone wrote:
Hi,
I've just started learning Haskell, and I must admit I'm finding it a bit hard to get my head around the typing system...
If I wanted to represent Employees and Departments in a Haskell program I could use data declarations like so: data Employee = Emp ... data Department = Dept ...
This seems limited in (at least) two ways: I can't dynamically add fields to an employee or department, and once I pull a field out of an instance I lose type information.
What I want to be able to do is add and remove fields while the system is running, I suppose via hs-plugins, and I should be prevented from, for example, accidentally taking an employees first name and using it as a departments address.
My first attempt was the following, which isn't even valid and doesn't appear to buy me much anyway.
class DataContainer c
class DataContainer c => DataField f c a where extract :: f -> a apply :: (a -> a -> a) -> f -> f -> f
data DataContainer c => Field c a = Fld c a instance DataField Field c a where extract (Fld _ a) = a apply f (Fld c a1) (Fld _ a2) = Fld c (f a1 a2)
data Employee = Emp instance DataContainer Employee
data Department = Dept instance DataContainer Department
type EmployeeName = Field Employee String type EmployeeAddress = Field Employee String type EmployeeIdentifier = Field Employee Integer type DepartmentAddress = Field Department String type DepartmentIdentifier = Field Department Integer ...
The 'DataField instance Field' declaration gives kind errors regarding how many type arguments Field is applied to. I don't claim to understand kinds at this point. Even if it did work, apply doesn't appear to force the arguments to be of the same type, and the declared type synonyms aren't enough to prevent me getting employee names and addresses confused.
Is there a correct way to express what I'm trying to do? Or is it a bad idea to start with?
Thanks Karl _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On 9/20/05, Karl Grapone
What I want to be able to do is add and remove fields while the system is running, I suppose via hs-plugins, and I should be prevented from, for example, accidentally taking an employees first name and using it as a departments address.
I know the HList paper - http://homepages.cwi.nl/~ralf/HList/ - demonstrates type-safe extensible records. However, the type classery behind it may not be totally obvious at first depending on how new to Haskell you are. /g

Karl Grapone
I've just started learning Haskell, and I must admit I'm finding it a bit hard to get my head around the typing system...
Okay.
What I want to be able to do is add and remove fields while the system is running,
While I'm sure you'll get some advanced replies to this, IMHO there is a contradiction between static (ie. compile time) type safety, and run-time modification of the types. If you are happy with dynamic typing, I would encode the data fields as lists of (keyword,value) pairs, and insert the necessary checks where appropriate. I.e. something like: type Keyword = String -- alternative: data Keyword = Name | Address |.. type Value = String -- or: data KeyVal = Name String | Number Int |.. data Employee = E [(Keyword,Value)] data Department = D [(Keyword,Value)] You can easily look up and update the field lists by using standard Prelude funcitions. -k -- If I haven't seen further, it is by standing in the footprints of giants
participants (4)
-
J. Garrett Morris
-
Karl Grapone
-
Ketil Malde
-
Marc Ziegert