In the first case, we have
liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
(==) :: Eq a => a -> a -> Bool
setting a1=aand a2=aget
liftM2 (==) :: (Eq a, Monad m) => m a -> m a -> m Bool
Now the tricky bit is that there is a Monad instance for a function type .
instance Monad ((->) r) where
return = const
f >>= k = \ r -> k (f r) r
because of this, a function of the type r -> awhere a is expected can be passed Monad a => m a. Since id :: a -> awe obtain r=a, m a = a -> aand m Bool = a -> Bool, which leads to
liftM2 (==) id :: (Eq a) => (a -> a) -> (a -> Bool)
For the second type, what this type signature says, there is a Num instance for the function type (a -> a).
Haskell , ((\x -> x + 1) id) :
((\x -> x + (fromInteger 1)) id)
β-
id + (fromInteger 1)
, (fromInteger 1) +. , Haskell , .
{-# 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