Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding function types

I am getting a bit confused in my attempts to understand how Haskell determines function types. Here is an example:

boolFcn x y = x/=3 && y/=4

When I check the type of the above function, it gives me result:

(Num a1, Num a, Eq a1, Eq a) => a -> a1 -> Bool

Here is another example:

triangles = [ (a,b,c) | c <- [1..10], b <- [1..10], a <- [1..10] ]   

And apllying :t on triangles results with:

(Num t2, Num t1, Num t, Enum t2, Enum t1, Enum t) =>  [(t, t1, t2)]

A few questions arised in my head and I have serious trouble solving them by myself:

  1. Why does the type of boolFcn consists of a, a1 literals whilst the type of triangles consists of t,t1 literals? Is there any difference between a and t?
  2. Why does this the type of boolFcn cannot be simplified to:

    (Num a, Eq a) => a -> a -> Bool

a and a1 have the same typeclasses, so why can't I just simply write them using one a? When I check type of the function:

let sumthis x y = if x > y then x+y else x-y

I get a result:

(Ord a, Num a) => a -> a -> a

Why doesn't it result in:

(Ord a, Num a, Ord a1, Num a1) => a -> a1 -> a

I'm sorry if the question is trivial, though I would gladly hear any explanations/hints to this problem.

like image 353
TheMP Avatar asked Dec 26 '22 07:12

TheMP


1 Answers

  1. Yes, a and t are essentially the same in these examples. The difference is just a side effect of the type inference algorithms.

  2. Well, in boolFcn, (Num a, Eq a) => a -> a -> Bool would not be general enough, because the first two arguments need not be the same type. Consider the following call:

    boolFcn (4::Int) (4::Double)

    This is valid, because Int and Double are both members of the Num and Eq typeclasses, but they are clearly not the same type. In your sumthis example, x and y must be the same type because they are used as inputs to functions that require arguments of the same type.

    We can see that by checking :t (+), which returns (+) :: Num a => a -> a -> a. Since the parameters of + must be the same type, x and y must be the same type, so sumthis must require arguments of the same type. Therefore

    sumthis (4::Int) (4::Double)

    would not be valid.

like image 139
Jeff Burka Avatar answered Jan 10 '23 08:01

Jeff Burka