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
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 a
s 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 a
s.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With