user4132
user4132

Reputation: 417

When does Haskell complain about incorrect typing in functions?

I am a Haskell newbie trying to wrap my head around type binding in functions and how Haskell enforces it. For example, even though the type for the fst function is fst :: (a, b) -> a, the compiler does not complain for the function fst'. But the compiler complains about type bindings for the function elem'.

fst' :: (a,a) -> a
fst' s = fst s

elem' :: (Eq a, Eq b) => a -> [b] -> Bool
elem' x xs = elem x xs

Upvotes: 20

Views: 1135

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477065

fst has as type fst :: (a, b) -> a so that means it is fine to define a function:

fst' :: (a, a) -> a
fst' = fst

Your fst' function is more restrictive than the fst function. Regardless with what you replace a in your fst' function that is fine for fst. If for example a ~ Bool holds, then you call fst with signature fst :: (Bool, Bool) -> Bool. But since fst can deal with all as and b, it is fine that both elements of the tuple are Bool, so given fst can handle tuples for all possible types for both the first and the second item of the 2-tuple, it is defintely ok if the two items have the same type.

The latter is not ok, here you define:

elem' :: (Eq a, Eq b) => a -> [b] -> Bool
elem' = elem

but elem has type elem :: Eq a => a -> [a] -> Bool. The signatures you can make with the elem' function are not a subset of the ones of the elem function, since you can set a ~ Int and b ~ Bool. In that case you expect elem :: Int -> [Bool] -> Bool, but evidently that does not hold, since the Int and Bool type are two different types, and in the elem signature, these are both as.

Upvotes: 32

Related Questions