Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type error while writing max function

Tags:

haskell

max' :: Int -> Int -> Int
max' a b = if a >= b then a else b 

you see that the function is correct but if i write

let a = 3,
let b = 3

and also if i write

ghci> a == b => True

so it compares them then why it doesn't compare in my function

ghci> max' a b 

error occurs why? or what is the right way to write it?

Sorry I am beginner if my question is silly forgive me for that and edit it if there is a need for that Thanks

<interactive>:19:6:
    Couldn't match expected type `Int' with actual type `Integer'
    In the first argument of max', namely `a'
    In the expression: max' a b
    In an equation for `it': it = max' a b

<interactive>:19:8:
    Couldn't match expected type `Int' with actual type `Integer'
    In the second argument of max', namely `b'
    In the expression: max' a b
    In an equation for `it': it = max' a b
like image 260
user2999428 Avatar asked Dec 20 '22 21:12

user2999428


2 Answers

I guess you are doing this in the ghci interpreter. Then, have a look at (:t displays the type of an expression and a line of the form a :: t means a has type t):

Prelude> let a = 3
Prelude> :t a
a :: Integer

The ghci interpreter commits early and gives a the type Integer though it should give any numeric type (thus a :: Num t => t).

Now, your function receives Ints as arguments but since a and b are Integers you get that error message.

You can either remove the restrictive type signature or you can define a and b to be Ints. I'd go with the first option, unless there is some requirement to go with Int-only type signature. To do so you need to add ::Int at the end of the definition:

Prelude> let b = 42 :: Int
Prelude> :t b
b :: Int

If you want to remove the signature recode your function to have only one line:

max' a b = if a >= b then a else b 

Now, if you're to inspect its type:

Prelude> :t max'
max' :: Ord a => a -> a -> a

Which means you've got a generic function which works for any type which can be ordered.

An alternative is to start ghci using an extension: ghci -XNoMonomorphismRestriction. In this case:

Prelude> let a = 3
Prelude> :t a
a :: Num a => a

which will work directly on your function.

The reason why ghci without this extension commits to Integer is the Monomorphism restriction

like image 185
Mihai Maruseac Avatar answered Jan 27 '23 08:01

Mihai Maruseac


When you use let a = 3, the type of a will be Integer, not Int. You can check this by using :t a in ghci. You can use let a = 3 :: Int to ensure that you get the correct type:

ghci>let a = 3 :: Int
ghci>let b = 3 :: Int
ghci>max' a b 
like image 42
Zeta Avatar answered Jan 27 '23 08:01

Zeta