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' |
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 |
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 |
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 |
Free forum by Nabble | Edit this page |