
{- Hi, Consider the following Haskell data, class and instance definitions The intended semantics are: Two objects are equal if they have the same name. The type of the name depends on the type of the object -} data Object a = Object a class Named o n | o -> n where name :: o -> n instance (Eq n, Named o n) => Eq o where o1 == o2 = name(o1) == name(o2) {- I have three questions about these definitions. 1) Does the above code capture the intended meaning? 2) Does Object a *fit* the Named class?, or do I need a different sort of Object? 3) How would I write an instance of Named that implements the name function correctly. Thomson[1] shows how to do this for non-dependent types [1]Haskell: The Craft of Functional Programming, Second Edition, Page 272 -}

The intended semantics are: Two objects are equal if they have the same name. The type of the name depends on the type of the object
3) How would I write an instance of Named that implements the name function correctly.
I think (but someone with better knowledge) the term "dependent type" means something else: http://en.wikipedia.org/wiki/Dependent_types I'm sure you'll be interested in type families, which offer a better and richer syntax to what you want: http://www.haskell.org/ghc/docs/latest/html/users_guide/type-families.html I tried rewriting your example using ghc-6.8.2 but I wasn't able to build it, and since ghc-6.8.* isn't actually supposed to properly support type families I though I could give you a bad example even if I get it to build :) So I'm leaving it here just in case someone wants to use it as a base: ------ module Main (main) where data (Eq a) => Object a = Object a class (Eq (NameType o)) => Named o where type NameType o :: * name :: o -> NameType o equals :: o -> o -> Bool equals o1 o2 = (name o1) == (name o2) instance (Named a) => Eq a where (==) = equals instance Named (Object Integer) where type NameType (Object Integer) = Integer name (Object i) = i f,g :: Object Integer f = Object 1 g = Object 2 main = putStrLn $ show $ f == g ------ Best, Maurício

Maurício, Thanks for your rapid feedback, I will study your code.
I think (but someone with better knowledge) the term "dependent type" means something else: http://en.wikipedia.org/wiki/Dependent_types
From your first link I think the term *dependent type* is defined as a type that depends on *values* of other types. The semantic that I am trying to express is that one type depends on another type. Specifically, the type of a name depends on the type of the object. For example a Person with a Name would give a Persons-Name and a Dog with a Name would give a Dogs-Name. The paper [1] describe several styles of dependency Types depending on values called dependent types Types depending on types called parametric and type-indexed types
[1]Comparing Approaches to Generic Programming Haskell by Hinze, Jeuring, and LÄoh Best regards, Pat Maurício wrote:
The intended semantics are: Two objects are equal if they have the same name. The type of the name depends on the type of the object
3) How would I write an instance of Named that implements the name function correctly.
I think (but someone with better knowledge) the term "dependent type" means something else:
http://en.wikipedia.org/wiki/Dependent_types
I'm sure you'll be interested in type families, which offer a better and richer syntax to what you want:
http://www.haskell.org/ghc/docs/latest/html/users_guide/type-families.html
I tried rewriting your example using ghc-6.8.2 but I wasn't able to build it, and since ghc-6.8.* isn't actually supposed to properly support type families I though I could give you a bad example even if I get it to build :) So I'm leaving it here just in case someone wants to use it as a base:
------ module Main (main) where
data (Eq a) => Object a = Object a
class (Eq (NameType o)) => Named o where type NameType o :: * name :: o -> NameType o equals :: o -> o -> Bool equals o1 o2 = (name o1) == (name o2)
instance (Named a) => Eq a where (==) = equals
instance Named (Object Integer) where type NameType (Object Integer) = Integer name (Object i) = i
f,g :: Object Integer f = Object 1 g = Object 2
main = putStrLn $ show $ f == g ------
Best, Maurício
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Specifically, the type of a name depends on the type of the object. For example a Person with a Name would give a Persons-Name and a Dog with a Name would give a Dogs-Name.
One radically simple way to get that would be something like this (you can also use 'newtype' instead of 'data'): -- warning: untested code -- data (Eq b) => Named a b = Named a b equivalent :: Named a b -> Named c b -> Bool equivalent (Named _ a1 ) (Named _ a2) = (a1 == a2) Then you can check Persons-Name and Dogs-Name (Named Persons Name and Named Dogs Name) for equivalence based only on their values of Name type. Note that you can't use (==) from Eq class because Persons-Name and Dogs-Name are different types, and Eq class uses only one when instanciated. If you would like to use a equivalence relashionship that is not limited to your parametric type you could write a class like this: class Equivalent a b where equivalent :: a -> b -> Bool instance (Eq b) => Equivalent (Named a b) (Named c b) where ...
Thanks for your rapid feedback, I will study your code.
Instead, study Felipe's example. It shows a nice way to "attach" a name to anything, and shows some interesting classes you will like to learn. Best, Maurício

Maurício wrote:
-- warning: untested code --
data (Eq b) => Named a b = Named a b
equivalent :: Named a b -> Named c b -> Bool equivalent (Named _ a1 ) (Named _ a2) = (a1 == a2)
which doesn't work. "data (Eq b) =>" is useless broken syntax that should be removed from the standard. Either you can use data Named a b = Named a b equivalent :: (Eq b) => Named a b -> Named c b -> Bool or use some GHC extension (GADTs) and do data Named a b where Named :: (Eq b) => a -> b -> Named a b equivalent :: Named a b -> Named c b -> Bool -Isaac

On Mon, Jul 20, 2009 at 05:46:14PM -0300, Maurício wrote:
data (Eq a) => Object a = Object a
I'd rewrite this as newtype Object a = Object a
instance (Named a) => Eq a where (==) = equals
Be careful with this instance! (specially since this is haskell-beginners)
instance Named (Object Integer) where type NameType (Object Integer) = Integer name (Object i) = i
I'd rewrite this as instance Eq a => Named (Object a) where type NameType (Object a) = a name (Object a) = a instance Eq a => Eq (Object a) where (==) = equals However, I guess something like data Name n a = Name n a instance Functor (Name n) where fmap f (Name n a) = Name n (f a) instance Eq n => Named (Name n a) where type NameType (Name n a) = n name (Name n _) = n instance Copointed (Name n) where -- from category-extras extract (Name _ a) = a would be a whole lot more useful, no? -- Felipe.
participants (4)
-
Felipe Lessa
-
Isaac Dupree
-
Maurício
-
pat browne