[Haskell-beginners] Data Class problem

Markus Läll markus.l2ll at gmail.com
Fri Aug 20 08:20:20 EDT 2010


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


More information about the Beginners mailing list