Send Beginners mailing list submissions to
[email protected]
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
[email protected]
You can reach the person managing the list at
[email protected]
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 <[email protected]>
Subject: Re: [Haskell-beginners] Data Class problem
To: Michael Bradley <[email protected]>
Cc: [email protected]
Message-ID:
<[email protected]>
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 <[email protected]>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
> [email protected]
> 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 <[email protected]>
Subject: Re: [Haskell-beginners] Data Class problem
To: [email protected]
Message-ID:
<[email protected]>
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 <[email protected]> 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
> <[email protected]>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
>> [email protected]
>> http://www.haskell.org/mailman/listinfo/beginners
>>
>>
>
------------------------------
Message: 3
Date: Fri, 20 Aug 2010 14:25:56 +0100
From: Brent Yorgey <[email protected]>
Subject: Re: [Haskell-beginners] Data Class problem
To: [email protected]
Message-ID: <[email protected]>
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
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 26, Issue 41
*****************************************