[Haskell-beginners] Data Class problem

Brent Yorgey byorgey at seas.upenn.edu
Fri Aug 20 09:25:56 EDT 2010


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 at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners



More information about the Beginners mailing list