[Haskell-beginners] Functor question.

Phillip Pirrip ppirrip at gmail.com
Sun Nov 15 23:34:39 EST 2009


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

> On Sun, Nov 15, 2009 at 7:50 PM, Phillip Pirrip <ppirrip at gmail.com> 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
>> Beginners at haskell.org
>> 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





More information about the Beginners mailing list