Why this does not work exactly?
sum :: (Num a, Num b) => a -> b -> c
sum a b = a + b
For sure, the error message is related to the signature but I continue to not understand the reason.
Couldn't match expected type ‘a’ with actual type ‘b’
‘b’ is a rigid type variable bound by
the type signature for:
sum :: forall a b c. (Num a, Num b) => a -> b -> c
‘a’ is a rigid type variable bound by
the type signature for:
sum :: forall a b c. (Num a, Num b) => a -> b -> c
In the second argument of ‘(+)’, namely ‘b’
In the expression: a + b
In an equation for ‘sum’: sum a b = a + b
What Am I missing?
From HaskellWiki. A type signature is a line like. inc :: Num a => a -> a. that tells, what is the type of a variable. In the example inc is the variable, Num a => is the context and a -> a is its type, namely a function type with the kind * -> * .
Since the type of elem y z is Bool , this matches with the function (&&) x , and thus the type of (&&) x (elem y z) is thus Bool .
In b Bool , b stands for a parametrized type that takes one type parameter (in Haskell parlance, b is a type constructor of kind * -> * ), such as Maybe , IO or [] .
There is no Order By the way, Haskell is a lazy language, so things are not evaluated in the order you write them. Instead they are evaluated when the values are needed.
Because the (+)
function has signature:
(+) :: Num a => a -> a -> a
So that means that the (+)
function requires the operands to have the same type, and the result has the same type as the operands.
Your signature would mean that a programmer can pick any Num
type as first operand, and any Num
type as second operand, and then construct any type. So it would mean that I could specialize the function into sum :: Int -> Float -> Char
, but there is no such (+)
defined.
We can make the type more flexible, for instance by using fromIntegral :: (Integral a, Num b) => a -> b
:
integralSum :: (Integral i, Integral j, Num c) => i -> j -> c
integralSum x y = fromIntegral x + fromIntegral y
For a different answer let's try ignoring everything besides the type signature.
sum :: (Num a, Num b) => a -> b -> c
This says that if I give you a value of some type and all you know is it is an instance of Num
(the a
type variable), and I give you a second value which could be a different type but also a Num
(the b
type variable), then you know how to give me a value of any type I ask for (c
).
That is, I'm going to give you (3%4 :: Rational)
and (7.99 :: Double)
could you please give me val :: Config
which is the configuration structure for my web server? The expression sum (3%4) 7.99 :: Config
matches your type signature after all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With