Functor question.

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Functor question.

Phillip Pirrip

Hi,

When I define my data as fellow,

data Moo a = Moo a
            deriving (Show)

instance Functor Moo where
   fmap f (Moo a) = Moo (f a)

GHC gives me no problem.  Then I add something,

data (Num a) => Moo a = Moo a
            deriving (Show)

instance Functor Moo where
   fmap f (Moo a) = Moo (f a)

Now GHC gives me the follow error - see bellow.

What is the reason behind this?  What should I do to correct this?

thx,

//

matFun_v2.hs:16:12:
   Could not deduce (Num a) from the context ()
     arising from a use of `Moo' at matFun_v2.hs:16:12-14
   Possible fix:
     add (Num a) to the context of the type signature for `fmap'
   In the pattern: Moo a
   In the definition of `fmap': fmap f (Moo a) = Moo (f a)
   In the instance declaration for `Functor Moo'

matFun_v2.hs:16:21:
   Could not deduce (Num b) from the context ()
     arising from a use of `Moo' at matFun_v2.hs:16:21-29
   Possible fix:
     add (Num b) to the context of the type signature for `fmap'
   In the expression: Moo (f a)
   In the definition of `fmap': fmap f (Moo a) = Moo (f a)
   In the instance declaration for `Functor Moo'
Reply | Threaded
Open this post in threaded view
|

Functor question.

Alexander Dunlap
On Sun, Nov 15, 2009 at 7:50 PM, Phillip Pirrip <[hidden email]> wrote:

>
> Hi,
>
> When I define my data as fellow,
>
> data Moo a = Moo a
> ? ? ? ? ? ?deriving (Show)
>
> instance Functor Moo where
> ? fmap f (Moo a) = Moo (f a)
>
> GHC gives me no problem. ?Then I add something,
>
> data (Num a) => Moo a = Moo a
> ? ? ? ? ? ?deriving (Show)
>
> instance Functor Moo where
> ? fmap f (Moo a) = Moo (f a)
>
> Now GHC gives me the follow error - see bellow.
>
> What is the reason behind this? ?What should I do to correct this?
>
> thx,
>
> //
>
> matFun_v2.hs:16:12:
> ? Could not deduce (Num a) from the context ()
> ? ? arising from a use of `Moo' at matFun_v2.hs:16:12-14
> ? Possible fix:
> ? ? add (Num a) to the context of the type signature for `fmap'
> ? In the pattern: Moo a
> ? In the definition of `fmap': fmap f (Moo a) = Moo (f a)
> ? In the instance declaration for `Functor Moo'
>
> matFun_v2.hs:16:21:
> ? Could not deduce (Num b) from the context ()
> ? ? arising from a use of `Moo' at matFun_v2.hs:16:21-29
> ? Possible fix:
> ? ? add (Num b) to the context of the type signature for `fmap'
> ? In the expression: Moo (f a)
> ? In the definition of `fmap': fmap f (Moo a) = Moo (f a)
> ? In the instance declaration for `Functor Moo'
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/beginners
>

Your datatype Moo cannot be an instance of Functor because Moo cannot
contain all types. fmap takes a function of type (a -> b), which means
that the function can be from *any* type a to *any* type b, and
produces a function of type (f a -> f b), which in your case means Moo
a -> Moo b. But the function fmap f (Moo x) = Moo (f x) does not have
type "a -> b"; it has type "(Num a, Num b) => a -> b", since if you
can have a type Moo a, a must be an instance of Num.

In general, people recommend against using constriants on datatypes,
recommending instead to put those constraints on the functions that
operate on the datatypes. I'm not quite sure why that is, though.

Alex
Reply | Threaded
Open this post in threaded view
|

Functor question.

Phillip Pirrip

On 2009-11-15, at 11:07 PM, Alexander Dunlap wrote:

> On Sun, Nov 15, 2009 at 7:50 PM, Phillip Pirrip <[hidden email]> wrote:
>>
>> Hi,
>>
>> When I define my data as fellow,
>>
>> data Moo a = Moo a
>>            deriving (Show)
>>
>> instance Functor Moo where
>>   fmap f (Moo a) = Moo (f a)
>>
>> GHC gives me no problem.  Then I add something,
>>
>> data (Num a) => Moo a = Moo a
>>            deriving (Show)
>>
>> instance Functor Moo where
>>   fmap f (Moo a) = Moo (f a)
>>
>> Now GHC gives me the follow error - see bellow.
>>
>> What is the reason behind this?  What should I do to correct this?
>>
>> thx,
>>
>> //
>>
>> matFun_v2.hs:16:12:
>>   Could not deduce (Num a) from the context ()
>>     arising from a use of `Moo' at matFun_v2.hs:16:12-14
>>   Possible fix:
>>     add (Num a) to the context of the type signature for `fmap'
>>   In the pattern: Moo a
>>   In the definition of `fmap': fmap f (Moo a) = Moo (f a)
>>   In the instance declaration for `Functor Moo'
>>
>> matFun_v2.hs:16:21:
>>   Could not deduce (Num b) from the context ()
>>     arising from a use of `Moo' at matFun_v2.hs:16:21-29
>>   Possible fix:
>>     add (Num b) to the context of the type signature for `fmap'
>>   In the expression: Moo (f a)
>>   In the definition of `fmap': fmap f (Moo a) = Moo (f a)
>>   In the instance declaration for `Functor Moo'
>> _______________________________________________
>> Beginners mailing list
>> [hidden email]
>> http://www.haskell.org/mailman/listinfo/beginners
>>
>
> Your datatype Moo cannot be an instance of Functor because Moo cannot
> contain all types. fmap takes a function of type (a -> b), which means
> that the function can be from *any* type a to *any* type b, and
> produces a function of type (f a -> f b), which in your case means Moo
> a -> Moo b. But the function fmap f (Moo x) = Moo (f x) does not have
> type "a -> b"; it has type "(Num a, Num b) => a -> b", since if you
> can have a type Moo a, a must be an instance of Num.
>
> In general, people recommend against using constriants on datatypes,
> recommending instead to put those constraints on the functions that
> operate on the datatypes. I'm not quite sure why that is, though.
>
> Alex

Thanks Alex.  That is very clear.  I didn't expect that (Num a, Num b)=>a->b is actually different than a->b from the compiler point of view.  I was under the assumption that the more constraint I put there the better for the compiler.

//pip



Reply | Threaded
Open this post in threaded view
|

Functor question.

Brent Yorgey-2
In reply to this post by Alexander Dunlap
On Sun, Nov 15, 2009 at 08:07:36PM -0800, Alexander Dunlap wrote:
>
> In general, people recommend against using constriants on datatypes,
> recommending instead to put those constraints on the functions that
> operate on the datatypes. I'm not quite sure why that is, though.

It is because adding a constraint to a datatype definition only puts a
constraint on the *constructor*---in particular, you don't get any
constraints when pattern-matching, and you have to put the constraints
on functions that operate on the datatype anyway.

-Brent