I am studying haskell. Could somebody explain how the two types are inferred and what does Num (a -> a) mean?
liftM2 (==) id :: Eq a => (a -> a) -> a -> Bool
(\x->x+1) id :: Num (a -> a) => a -> a
I am studying haskell. Could somebody explain how the two types are inferred and what does Num (a -> a) mean?
liftM2 (==) id :: Eq a => (a -> a) -> a -> Bool
(\x->x+1) id :: Num (a -> a) => a -> a
In the first case we have
liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
(==) :: Eq a => a -> a -> Bool
by setting a1=a
and a2=a
we get
liftM2 (==) :: (Eq a, Monad m) => m a -> m a -> m Bool
Now the tricky bit is that there is a Monad instance for the function type.
instance Monad ((->) r) where
return = const
f >>= k = \ r -> k (f r) r
because of this, a function of type r -> a
can be passed where a Monad a => m a
is expected. Since id :: a -> a
we get r=a
, m a = a -> a
and m Bool = a -> Bool
, resulting in
liftM2 (==) id :: (Eq a) => (a -> a) -> (a -> Bool)
For the second type, what that type signature is saying is that there is a Num instance for the function type (a -> a)
.
Haskell numeric literals are polymorphic and ((\x -> x + 1) id)
is actually syntactic sugar for the following:
((\x -> x + (fromInteger 1)) id)
which, by β-reduction is
id + (fromInteger 1)
This assumes that (fromInteger 1) is a function and that there is a way to add two functions together with the +
operator. By default this is not possible but Haskell allows you to define addition for functions if you really want to.
{-# LANGUAGE FlexibleInstances #-}
instance Num (Int -> Int) where
f + g = \x -> f x + g x
f * g = \x -> f x * g x
abs f = \x -> abs (f x)
fromInteger n = \x -> fromInteger n
signum f = error "not implemented"
f1 :: Int -> Int
f1 x = x + 1
f2 :: Int -> Int
f2 x = x + 2
f3 :: Int -> Int
f3 = f1 + f2
main = do
print $ f3 0