Haskell Signatures: The Basics

Why does this not work for sure?

sum :: (Num a, Num b) => a -> b -> c sum ab = a + b 

Of course, the error message is related to the signature, but I still don't 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 ab c. (Num a, Num b) => a -> b -> c 'a' is a rigid type variable bound by the type signature for: sum :: forall ab 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 ab = a + b 

What am I missing?

+5
source share
3 answers

Since the function (+) has a signature:

 (+) :: Num a => a -> a -> a 

Thus, this means that the (+) function requires that the operands be of the same type , and the result is of the same type as the operands.

Your signature will mean that the programmer can select any type of Num as the first operand, and any type of Num as the second operand, and then build any type. Therefore, this would mean that I could specialize the function in sum :: Int -> Float -> Char , but this (+) does not exist.

We can make the type more flexible, for example, using fromIntegral :: (Integral a, Num b) => a -> b :

 integralSum :: (Integral i, Integral j, Num c) => i -> j -> c integralSum xy = fromIntegral x + fromIntegral y 
+8
source

For a different answer, try to ignore everything except the type signature.

 sum :: (Num a, Num b) => a -> b -> c 

This suggests that if I give you a value of some type and all you know is an instance of Num (a variable of type a ), and I will give you a second value, which may be of a different type but also a variable of type Num (variable type b ), then you know how to give me a value of any type that I ask for ( c ).

That is, I will give you (3%4 :: Rational) and (7.99 :: Double) , please give me val :: Config , which is the configuration structure for my web server? The expression sum (3%4) 7.99 :: Config ultimately matches your type signature.

+7
source

Let's look at the type of operator + . We can do this in ghci with the command :t :

 Prelude> :t (+) (+) :: Num a => a -> a -> a 

Please note that both operand and return value must be of the same type. This is why you get compiler errors. You allow sum to accept operands of two different types. So you can change your type signature to

 sum :: (Num a, Num a) => a -> a -> a 

If you want to add numbers of different types, you need additional logic to convert the parameters to the same type before using the + operator.

+5
source

Source: https://habr.com/ru/post/1275148/


All Articles