there's an error I come across all the time but can't understand how to make it right. An example of code that gives me this error is:
class Someclass a where
somefunc :: (Num b) => b -> a -> a
data Sometype = Somecons Int
instance Someclass Sometype where
somefunc x (Somecons y) = Somecons (x+y)
The error message is:
Couldn't match expected type 'b' against inferred type 'Int'
'b' is a rigid type variable bound by the type signature for 'somefunc' at error.hs:3:21
In the second argument of '(+)', namely 'y'
In the first argument of 'Somecons', namely '(x + y)'
In the expression: Somecons (x + y)
I understand that the error message is trying to tell me that I used a name of type Int where he was expecting something with type (Num b) => b. What I can't understand is that Int fits in (Num b)=>b. Shouldn't the compiler understand what I'm telling him (that for this specific instance b should be an integer? How can I make this fit?
Coment: Of course in this specific example I could have made somefunc with type signature:
somefunc :: a -> a-> a
but supose I wanted something like:
data Newtype = Newcons (Int, Int)
instance Someclass Newtype where
somefunc x (Newtype (y,z) ) = Newtype (y+x, z)
Things like that recurrently happens when I'm trying to do something in haskell.
Well, you can make the point clearer when thinking of the generics notation using universal quantification.
somefunc :: (Num b) => b -> a -> a
therefore means nothing but
somefunc :: forall a b . Num b => b -> a -> a
This means your class function must be defined for any numeric b
.
The code
Data Sometype = Somecons Int
instance Someclass Sometype where
somefunc x (Somecons y) = Somecons (x+y)
forces b
to have one concrete type - Int
, which doesn't conform with the requirement to work for any numeric type.
You might want to have something like this
class Num b => SomeClass a b where
somefunc :: b -> a -> a
instance Someclass Somecons Int where
-- ...