
I'm learning how to use typeclasses for the first time, and I tried something like so: [CODE] data Point a = Point a a getX (Point a _) = a getY (Point _ a) = a instance Eq Point where (==) a b = getX a == getX b && getY a == getY b [/CODE] But when I try to load this in GHCI I get: [CODE] `Point' is not applied to enough type arguments The first argument of `Eq' should have kind `*', but `Point' has kind `* -> *' In the instance declaration for `Eq Point' [/CODE] This seems to be saying that Eq requires a concrete argument, which I suppose I can understand. I can fix this by changing "data Point a = Point a a" into "data Point = Point Int Int" or something like that, but that seems kind of lame: what if I want to leave my Point type more generic? (Maybe sometimes I'll need a Point Int, and other times I'll need a Point Float, or some other weird combination I haven't thought of yet.) Instead of changing the "data" declaration, can I change the "instance" declaration somehow so that it just defines an instance for a particular Point sub-type? I tried some variations like "instance Eq (Point Float)" but I haven't been able to come up with anything yet that satisfies the compiler. -- frigidcode.com theologia.indicium.us

Hi Christopher, Try this instead: instance Eq (Point a) where .. Eq needs to take a type of kind `*', meaning the type itself doesn't have any type variables left. `Point' by itself is a type 'constructor', if you will, that needs another type to complete it (thus you can imagine it's like a 'type function' of kind `* -> *', meaning you need to give one type (`*') to yield a type `*'). You can just use `a' (or whatever) to represent any type filled in there, however. HTH! Arlen On Mon, 2011-05-09 at 19:25 -0800, Christopher Howard wrote:
I'm learning how to use typeclasses for the first time, and I tried something like so:
[CODE] data Point a = Point a a
getX (Point a _) = a getY (Point _ a) = a
instance Eq Point where (==) a b = getX a == getX b && getY a == getY b [/CODE]
But when I try to load this in GHCI I get:
[CODE] `Point' is not applied to enough type arguments The first argument of `Eq' should have kind `*', but `Point' has kind `* -> *' In the instance declaration for `Eq Point' [/CODE]
This seems to be saying that Eq requires a concrete argument, which I suppose I can understand.
I can fix this by changing "data Point a = Point a a" into "data Point = Point Int Int" or something like that, but that seems kind of lame: what if I want to leave my Point type more generic? (Maybe sometimes I'll need a Point Int, and other times I'll need a Point Float, or some other weird combination I haven't thought of yet.)
Instead of changing the "data" declaration, can I change the "instance" declaration somehow so that it just defines an instance for a particular Point sub-type? I tried some variations like "instance Eq (Point Float)" but I haven't been able to come up with anything yet that satisfies the compiler.

One further addendum to the answer provided by Arlen: Notice that instance Eq Point where (==) a b = getX a == getX b && getY a == getY b is defining equality between 'Point a' (as well pointed out by Arlen), but it does so in terms of equality test between 'a'... but there's no declaration in your code stating that 'a' can be equated. This all boils does to the following instance declaration: instance Eq a => Eq (Point a) where ... which reads nicely :) On Tue, 2011-05-10 at 13:35 +1000, Arlen Cuss wrote:
Hi Christopher,
Try this instead:
instance Eq (Point a) where ..
Eq needs to take a type of kind `*', meaning the type itself doesn't have any type variables left. `Point' by itself is a type 'constructor', if you will, that needs another type to complete it (thus you can imagine it's like a 'type function' of kind `* -> *', meaning you need to give one type (`*') to yield a type `*').
You can just use `a' (or whatever) to represent any type filled in there, however.
HTH!
Arlen
On Mon, 2011-05-09 at 19:25 -0800, Christopher Howard wrote:
I'm learning how to use typeclasses for the first time, and I tried something like so:
[CODE] data Point a = Point a a
getX (Point a _) = a getY (Point _ a) = a
instance Eq Point where (==) a b = getX a == getX b && getY a == getY b [/CODE]
But when I try to load this in GHCI I get:
[CODE] `Point' is not applied to enough type arguments The first argument of `Eq' should have kind `*', but `Point' has kind `* -> *' In the instance declaration for `Eq Point' [/CODE]
This seems to be saying that Eq requires a concrete argument, which I suppose I can understand.
I can fix this by changing "data Point a = Point a a" into "data Point = Point Int Int" or something like that, but that seems kind of lame: what if I want to leave my Point type more generic? (Maybe sometimes I'll need a Point Int, and other times I'll need a Point Float, or some other weird combination I haven't thought of yet.)
Instead of changing the "data" declaration, can I change the "instance" declaration somehow so that it just defines an instance for a particular Point sub-type? I tried some variations like "instance Eq (Point Float)" but I haven't been able to come up with anything yet that satisfies the compiler.
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On 05/09/2011 07:44 PM, Elvio Toccalino wrote:
One further addendum to the answer provided by Arlen:
Notice that
instance Eq Point where (==) a b = getX a == getX b && getY a == getY b
is defining equality between 'Point a' (as well pointed out by Arlen), but it does so in terms of equality test between 'a'... but there's no declaration in your code stating that 'a' can be equated. This all boils does to the following instance declaration:
instance Eq a => Eq (Point a) where ...
which reads nicely :)
Ah... Makes perfect sense now. Thanks! I'm glad I finally got around to joining this mailing list. -- frigidcode.com theologia.indicium.us
participants (3)
-
Arlen Cuss
-
Christopher Howard
-
Elvio Toccalino