
Hi, I am trying to understand the following code. I have written my current (mis-)understanding and questions below. I do not wish to improve the code, it is from a research paper[1] that I am trying to understand. Pat [1] ftp://ftp.geoinfo.tuwien.ac.at/medak/phdmedak.pdf -- A specification. The class Points takes two type variables. -- The functions take variables of type p, a; return a value of type a. class Points p a where getX :: p a -> a getY :: p a -> a -- A parameterized representation -- One constructor takes two elements of type a and produces a Point. data Point a = Pt a a -- An implementation of the class Points on the data type (Point a) -- In Pt b c constructor the variables b and c areboth of type a. -- The type a is left undefined until evaluation instance Points Point a where getX (Pt b c) = b getY (Pt b c) = c -- This runs with any type e.g. Integers -- getX(Pt 1 2) -- :t getX(Pt 1 2) -- getX(Pt 1 2) :: forall t. (Num t) => t My main question is in understanding the relationship between the arguments of the functions getX and getY in the class and in the instance. It seems to me that the constructor Pt 1 2 produces one element of type Point which has two components. How does this square with the class definition of getX which has two arguments? Is there a difference between: getX :: p a -> a and getX :: p -> a -> a This message has been scanned for content and viruses by the DIT Information Services E-Mail Scanning Service, and is believed to be clean. http://www.dit.ie

On 07/10/2011 12:49 PM, Patrick Browne wrote:
Hi, I am trying to understand the following code. I have written my current (mis-)understanding and questions below. I do not wish to improve the code, it is from a research paper[1] that I am trying to understand.
Pat [1] ftp://ftp.geoinfo.tuwien.ac.at/medak/phdmedak.pdf
-- A specification. The class Points takes two type variables. -- The functions take variables of type p, a; return a value of type a.
No. The class 'Points' takes two type variables, 'p' of kind (* -> *) (that is, p is a type constructor: it can be applied to a type, yielding a type), and 'a' of kind *. Then 'p a' is a type and getX, getY take /one/ argument respectively, of this type.
class Points p a where getX :: p a -> a getY :: p a -> a
-- A parameterized representation -- One constructor takes two elements of type a and produces a Point. data Point a = Pt a a
-- An implementation of the class Points on the data type (Point a)
Actually, it's an implementation (we say "instance") of the class Points for the type constructor 'Point' and any type 'a'.
-- In Pt b c constructor the variables b and c areboth of type a. -- The type a is left undefined until evaluation
I would say 'arbitrary' instead of 'undefined': The code below says that for any type of your choice, which we call 'a', you get an instance Points Point a.
instance Points Point a where getX (Pt b c) = b getY (Pt b c) = c
-- This runs with any type e.g. Integers -- getX(Pt 1 2) -- :t getX(Pt 1 2) -- getX(Pt 1 2) :: forall t. (Num t) => t
My main question is in understanding the relationship between the arguments of the functions getX and getY in the class and in the instance. It seems to me that the constructor Pt 1 2 produces one element of type Point which has two components. How does this square with the class definition of getX which has two arguments? Is there a difference between: getX :: p a -> a and getX :: p -> a -> a
Yes, the first version takes one argument of type 'p a', and the second takes two of types 'p' and 'a'. See above. This seemed to be you main issue. As a last note, if you always have instances like the one above, where the second parameter is arbitrary, your definition of the class 'Points' could be simplified to
class Points p where -- "forall a" is added implicitly. getX :: p a -> a getY :: p a -> a
instance Points Point where -- copy'n'paste from above
-- Steffen

On Sun, Jul 10, 2011 at 06:49, Patrick Browne
My main question is in understanding the relationship between the arguments of the functions getX and getY in the class and in the instance. It seems to me that the constructor Pt 1 2 produces one element of type Point which has two components. How does this square with the class definition of getX which has two arguments?
One argument. But your main confusion is between the data constructor which takes two arguments, and the type constructor which takes one. Point a -- type constructor, takes a type a and produces a new type Point a Pt a a -- data constructor, takes two values of some type a and produces a new value of type Point a Type constructors are used in type signatures; data constructors are used in code. You can't use Pt a a as a type; it's a (polymorphic) value. Conversely, you can't use Point a as a value (that is, "foo (Point a)" is an error, because foo requires a value, not a type). -- brandon s allbery allbery.b@gmail.com wandering unix systems administrator (available) (412) 475-9364 vm/sms

On Sun, 10 Jul 2011 11:49:44 +0100, Patrick Browne
My main question is in understanding the relationship between the arguments of the functions getX and getY in the class and in the instance. It seems to me that the constructor Pt 1 2 produces one element of type Point which has two components. How does this square with the class definition of getX which has two arguments? Is there a difference between: getX :: p a -> a
This applies the type constructor p, in this case Point to the type variable a. It is not a function that takes two arguments. A minor clarification: Pt 1 2 produces a value of type "(Num a) => Point a", so a type where the type constructor Point is already applied to something. Just "Point" is not a valid type a value can have, but something that you have to apply to another type, called a type constructor.
and getX :: p -> a -> a
This is a function that takes two arguments. Cheers, Daniel
participants (4)
-
Brandon Allbery
-
Daniel Schoepe
-
Patrick Browne
-
Steffen Schuldenzucker