
On 2009-11-15, at 11:07 PM, Alexander Dunlap wrote:
On Sun, Nov 15, 2009 at 7:50 PM, Phillip Pirrip
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@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