Re: [Haskell-cafe] class and instance
On Sun, Jul 10, 2011 at 06:49, Patrick Browne patrick.bro...@dit.ie wrote: 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 allber...@gmail.com wandering unix systems administrator (available) (412) 475-9364 vm/sms ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] class and instance
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 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] class and instance
On Sun, 10 Jul 2011 11:49:44 +0100, Patrick Browne patrick.bro...@dit.ie wrote: 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 pgpHx4UHpkIaI.pgp Description: PGP signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Class and Instance
Thanks for the feedback. I have two further questions 1. Why is it that the Containers class signature does not allow instances to be list of list? I suspect it is because x is a constructor. 2. How would I change the Containers class signature to allow instances to be lists of lists. Thanks, Pat -- x is a type constructor, not a type class Containers x y where insert :: y - x y - x y remove :: y - x y - x y whatsIn :: x y - [y] instance Containers [] Char where insert y [] = y:[] insert y m = y:m remove _ [] = [] remove x (y:ys) | x == y= remove x ys | otherwise = y : remove x ys whatsIn = id instance Containers [] Integer where insert y [] = y:[] insert y m = y:m remove _ [] = [] remove x (y:ys) | x == y= remove x ys | otherwise = y : remove x ys whatsIn = id -- cannot have containers of containers. -- instance Containers [] [] where -- container.hs:41:23: --`[]' is not applied to enough type arguments -- Expected kind `*', but `[]' has kind `* - *' -- In the instance declaration for `Containers [] []' -- Failed, modules loaded: none. 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 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Class and Instance
The problem is that [] alone is not a concrete type - that is what the error is saying, that [] needs to be applied to another type to yield a concrete type. IE, you need a list of something, not just the idea of a list. That something can be polymorphic, so the following works (note the [a]): class Containers x y where insert :: y - x y - x y {-remove :: y - x y - x y whatsIn :: x y - [y]-} instance Containers [] [a] where insert x y = x:y On Jun 11, 2011, at 5:49 AM, Patrick Browne wrote: Thanks for the feedback. I have two further questions 1. Why is it that the Containers class signature does not allow instances to be list of list? I suspect it is because x is a constructor. 2. How would I change the Containers class signature to allow instances to be lists of lists. Thanks, Pat -- x is a type constructor, not a type class Containers x y where insert :: y - x y - x y remove :: y - x y - x y whatsIn :: x y - [y] instance Containers [] Char where insert y [] = y:[] insert y m = y:m remove _ [] = [] remove x (y:ys) | x == y= remove x ys | otherwise = y : remove x ys whatsIn = id instance Containers [] Integer where insert y [] = y:[] insert y m = y:m remove _ [] = [] remove x (y:ys) | x == y= remove x ys | otherwise = y : remove x ys whatsIn = id -- cannot have containers of containers. -- instance Containers [] [] where -- container.hs:41:23: --`[]' is not applied to enough type arguments -- Expected kind `*', but `[]' has kind `* - *' -- In the instance declaration for `Containers [] []' -- Failed, modules loaded: none. 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 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Class and Instance
On Fri, 10 Jun 2011 17:28:22 +0100, Patrick Browne patrick.bro...@dit.ie wrote: -- Not OK -- insert 2 [9,2] This causes an error, because numeric literals like 2 are polymorphic: :t 2 2 :: Num a = a If you fix the type to Integer, it works as expected: insert (2 :: Integer) [9,2] By the way: It's helpful to include the error messages in your mail when some piece of code doesn't compile. Cheers, Daniel pgpiVLpuLW0ar.pgp Description: PGP signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Class and Instance
You can also modify you class if your intent is that it always work with polymorph types (And it will save you some trouble with functional dependencies between types x and y. Plus, it will be Haskell98 compliant) -- insert, remove and whatsIn are then supposed to work *forall y*, and then impose the kind of x to be * - * (x is a type constructor, not a mere type) class Container x where insert :: y - x y - x y remove :: y - x y - x y whatsIn :: x y - [y] Then you can do: import Data.List (delete) instance Container [] where insert = (:) remove = delete -- removes only the first occurence -- remove x = filter (/= x) -- if you want to remove *every* occurence of x (there may be a better way) whatsIn = id 2011/6/10 Patrick Browne patrick.bro...@dit.ie Hi Below is a class that I wish to create some instances of. I do not wish to change the class definition. It is supposed to represent containers of type x that contain things of type y. My attempt at the insert function seems ok for Char and lists, but not ok for Integer. How do I instantiate this class for integers and lists? Does this class definition permit y to be a list and hence x to be a list of lists? Something like: instance Containers [] [] where .. Is this a constructor class? Thanks, Pat class Containers x y where insert :: y - x y - x y remove :: y - x y - x y whatsIn :: x y - [y] instance Containers [] Char where insert y [] = y:[] insert y m = y:m instance Containers [] Integer where insert y [] = y:[] insert y m = y:m -- OK -- insert '1' ['u','u','l','i'] -- Not OK -- insert 2 [9,2] 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 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe