Send Beginners mailing list submissions to beginners@haskell.org To subscribe or unsubscribe via the World Wide Web, visit http://www.haskell.org/mailman/listinfo/beginners or, via email, send a message with subject or body 'help' to beginners-requ...@haskell.org
You can reach the person managing the list at beginners-ow...@haskell.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Beginners digest..." Today's Topics: 1. Re: Data Class problem (Jonas Almstr?m Dureg?rd) 2. Re: Data Class problem (Markus L?ll) 3. Re: Data Class problem (Brent Yorgey) ---------------------------------------------------------------------- Message: 1 Date: Fri, 20 Aug 2010 13:08:52 +0200 From: Jonas Almstr?m Dureg?rd <jonas.dureg...@chalmers.se> Subject: Re: [Haskell-beginners] Data Class problem To: Michael Bradley <michael.brad...@hotmail.co.uk> Cc: beginners@haskell.org Message-ID: <aanlktingq4cj+k3mcousn63gxff9spq3k93cv=gz-...@mail.gmail.com> Content-Type: text/plain; charset="iso-8859-1" Not sure if this helps, but when you have move :: Elements a => a It doesn't mean move will return some unknown Elements type, it means you can choose any type which is a member of elements and move will return that type. This means that Burn :: Elements a => a implies Burn :: Water Which is wrong. 3 :: Double 3 :: Integer are both correct on the other hand. /J On 20 August 2010 10:58, Michael Bradley <michael.brad...@hotmail.co.uk>wrote: > Hello all! > > I have been experimenting with data and class declarations and came across > a problem. I have been trying to do this: > > Code: > > data Fire = Burn | Ember > data Water = Bubble | WaterGun > > class Elements a > > instance Elements Fire > instance Elements Water > > data Elemental = Elemental { name :: String, > move :: (Elements a) => a > } > > So, the idea was that "move" in the data constructor "Elemental" would be > able to take any value from either the type Fire or Water. However, the > error message tells me this is an illegal polymorphic type. > > Therefore, I tried creating a function that could read my value for me > after "show" was applied to the move. Hence, the data declaration for > Elemental could now assign "move" to a String. The function looked like > this: > > Code: > > getMove :: (Elements b) => String -> b > getMove x = read x :: (Elements a) => a > > This will not work either, as the function "read" complains of ambiguity in > the letter a. I also tried this (amongst other attempts) > > Code: > > getMove :: (Elements b) => String -> b > getMove "Burn" = Burn > getMove "Ember" = Ember > getMove "Bubble" = Bubble > getMove "WaterGun" = WaterGun > getMove _ = error "Unknown move!" > > The above caused the function to infer the type Fire, and then complain > about the type Water. So, how can I either create a function that can return > multiple types like I am trying to above, or is there a way to adjust the > data declaration for Elemental? > > Also, I have noticed that 3 :: (Num a) => a will work but Burn :: > (Elements a) => a causes an ambiguity error. Why is this the case? > > Please help! > > Mike > > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20100820/30954259/attachment-0001.html ------------------------------ Message: 2 Date: Fri, 20 Aug 2010 15:20:20 +0300 From: Markus L?ll <markus.l...@gmail.com> Subject: Re: [Haskell-beginners] Data Class problem To: beginners@haskell.org Message-ID: <aanlktikwvanipuxwyk-3pwi1vojlquo=rqkn0dbxw...@mail.gmail.com> Content-Type: text/plain; charset=ISO-8859-1 I think the problem is, that in the datatype Elemental the compiler can't tell, what 'a' is. Both of these compile: {-# LANGUAGE ExistentialQuantification #-} ...code... data Elemental = forall a. (Elements a) => Elemental { name :: String, move :: a } or ...code... data Elemental a = Elemental { name :: String, move :: a } For the first, Elemental is an existentially quantified type over a, which takes any 'a' that is in the typeclass Elements. The second is a polymorphic type with a parameter 'a'. On 8/20/10, Jonas Almström Duregård <jonas.dureg...@chalmers.se> wrote: > Not sure if this helps, but when you have > > move :: Elements a => a > > It doesn't mean move will return some unknown Elements type, it means you > can choose any type which is a member of elements and move will return that > type. > > This means that > > Burn :: Elements a => a > > implies > > Burn :: Water > > Which is wrong. > > 3 :: Double > 3 :: Integer > > are both correct on the other hand. > > /J > > > On 20 August 2010 10:58, Michael Bradley > <michael.brad...@hotmail.co.uk>wrote: > >> Hello all! >> >> I have been experimenting with data and class declarations and came across >> a problem. I have been trying to do this: >> >> Code: >> >> data Fire = Burn | Ember >> data Water = Bubble | WaterGun >> >> class Elements a >> >> instance Elements Fire >> instance Elements Water >> >> data Elemental = Elemental { name :: String, >> move :: (Elements a) => a >> } >> >> So, the idea was that "move" in the data constructor "Elemental" would be >> able to take any value from either the type Fire or Water. However, the >> error message tells me this is an illegal polymorphic type. >> >> Therefore, I tried creating a function that could read my value for me >> after "show" was applied to the move. Hence, the data declaration for >> Elemental could now assign "move" to a String. The function looked like >> this: >> >> Code: >> >> getMove :: (Elements b) => String -> b >> getMove x = read x :: (Elements a) => a >> >> This will not work either, as the function "read" complains of ambiguity >> in >> the letter a. I also tried this (amongst other attempts) >> >> Code: >> >> getMove :: (Elements b) => String -> b >> getMove "Burn" = Burn >> getMove "Ember" = Ember >> getMove "Bubble" = Bubble >> getMove "WaterGun" = WaterGun >> getMove _ = error "Unknown move!" >> >> The above caused the function to infer the type Fire, and then complain >> about the type Water. So, how can I either create a function that can >> return >> multiple types like I am trying to above, or is there a way to adjust the >> data declaration for Elemental? >> >> Also, I have noticed that 3 :: (Num a) => a will work but Burn :: >> (Elements a) => a causes an ambiguity error. Why is this the case? >> >> Please help! >> >> Mike >> >> >> _______________________________________________ >> Beginners mailing list >> Beginners@haskell.org >> http://www.haskell.org/mailman/listinfo/beginners >> >> > ------------------------------ Message: 3 Date: Fri, 20 Aug 2010 14:25:56 +0100 From: Brent Yorgey <byor...@seas.upenn.edu> Subject: Re: [Haskell-beginners] Data Class problem To: beginners@haskell.org Message-ID: <20100820132556.ga27...@seas.upenn.edu> Content-Type: text/plain; charset=us-ascii Some others have suggested existential types, but that will not help here because the Elements class has no methods -- once you have wrapped up something in an existential Elements wrapper, there is literally nothing more you can do with it! I am not convinced that a type class is really what you want here. Type classes with no methods are rarely useful except for doing type-level programming. Why not just do something like this? data Element = Fire | Water data Item = Burn | Ember | Bubble | WaterGun elementOf :: Item -> Element elementOf Burn = Fire elementOf Ember = Fire ... etc data Elemental = Elemental { name :: String, move :: Item } -Brent On Fri, Aug 20, 2010 at 08:58:07AM +0000, Michael Bradley wrote: > > Hello all! > > I have been experimenting with data and class declarations and came across a > problem. I have been trying to do this: > > > > > Code: > data Fire = Burn | Ember > data Water = Bubble | WaterGun > > class Elements a > > instance Elements Fire > instance Elements Water > > data Elemental = Elemental { name :: String, > move :: (Elements a) => a > } > So, the idea was that "move" in the data constructor "Elemental" > would be able to take any value from either the type Fire or Water. > However, the error message tells me this is an illegal polymorphic type. > > > > Therefore, I tried creating a function that could read my value for me > after "show" was applied to the move. Hence, the data declaration for > Elemental could now assign "move" to a String. The function looked like > this: > > > > > Code: > getMove :: (Elements b) => String -> b > getMove x = read x :: (Elements a) => a > This will not work either, as the function "read" complains of > ambiguity in the letter a. I also tried this (amongst other attempts) > > > > > Code: > getMove :: (Elements b) => String -> b > getMove "Burn" = Burn > getMove "Ember" = Ember > getMove "Bubble" = Bubble > getMove "WaterGun" = WaterGun > getMove _ = error "Unknown move!" > The above caused the function to infer the type Fire, and then > complain about the type Water. So, how can I either create a function > that can return multiple types like I am trying to above, or is there a > way to adjust the data declaration for Elemental? > > > > Also, I have noticed that 3 :: (Num a) => a will work but Burn :: (Elements > a) => a causes an ambiguity error. Why is this the case? > > > > Please help! > > Mike > > > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners ------------------------------ _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners End of Beginners Digest, Vol 26, Issue 41 *****************************************