1
votes

I am a newbie to haskell and have a working code below as follows.

sum' :: (Num a) => [a] -> a
sum' [] = 0  
sum' (x:xs) = x + sum' xs 

What i try to do is to be more specific about my types.Instead of using 'a' only i try to write my code like that.

sum' :: (Num a, Num b) => [a] -> b
sum' [] = 0  
sum' (x:xs) = x + sum' xs 

When i do is i get an error.Error is as follows: Couldn't match expected type ‘b’ with actual type ‘a’ ‘a’ is a rigid type variable bound by the type signature for sum' :: (Num a, Num b) => [a] -> b at baby.hs:2:9 ‘b’ is a rigid type variable bound by the type signature for sum' :: (Num a, Num b) => [a] -> b at baby.hs:2:9

I think i don't really understand the meaning of '=>'. The part confuses me is what comes before '=>'. Sometimes a thing like that '(Show a) =>' and usually just types just like in my code. Please help thanks in advance.

2
The source of errors is that +'s type signature is Num a => a -> a -> a, i.e. it returns value of the same type as its arguments. But you want it to produce a value of a different type than it's arguments (b against as), which it simply cannot do.Michail
You are actually being less specific about your types. [a] -> b means you have no idea what type is being returned; the caller can specify anything they want. With [a] -> a, you are at least saying that the return type must be the same as the type stored in the input list.chepner

2 Answers

3
votes

Instead of using 'a' only i try to write my code like that.

This doesn't work because + requires two arguments of the same type, and returns a result of that very type.

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

Since there's no way to add two Integers and get back a Double, or add an Integer and a Double, there is also no way to sum a list of Integers and get back a Double.

Num a => means that the type a must be a number. More precisely, it requires that there is an instance Num a of the type class Num exists.

More info about type classes can be found here

0
votes

In the first code snippet, you're saying "Take a list of as (that are an instance of typeclass Num), and return something that's the same type as the elements in that list (that type is represented by a in the entire type signature)." That's what you want.

The second snippet says "Take a list of as (that are an instance of typeclass Num), and return something of type b, a different type." Since (+) returns the same type as its parameters, your function must as well.

The Num a in your first snippet applies to all as in the type signature, so there's no reason to split them into a and b.