
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