Could you please help me verify evaluation of following Haskell expression: fmap (*3) (+5) 1 ? I struggle especially with the correct parsing of the fmap x y z.
Thank you
My trial:
fmap (*3) (+5) 1 -- nothing to do 1 is 1
=> (fmap (*3)) (+5) 1 -- function application infixl 10
=> ((fmap (*3)) (+5)) 1 -- function application infixl 10
=> ((fmap (*3) (+5)) 1 -- (f (x) y) equivalent to (f x y)
=> ((*3) . (+5)) 1 -- fmap f g = f.g;
=> (*3) ((+5) 1) -- (f.g) x = f (g x)
=> (*3) 6
=> 18
The reasoning you demonstrate seems correct.
We can make a more rigorous answer on how Haskell does it. First the type checker will be activated.
Haskell sees the expression
((fmap (*3)) (+5)) 1
So first it does some type reasoning:
fmap :: Functor f => (a -> b) -> f a -> f b
(*3) :: Num c => c -> c
(+5) :: Num d => d -> d
1 :: Num e => e
Since we call fmap
with (*3)
this thus means that a -> b ~ c -> c
, and thus a ~ b ~ c
, so we get:
fmap :: (Num a, Functor f) => (a -> a) -> f a -> f a
(*3) :: Num a => a -> a
(+5) :: Num d => d -> d
1 :: Num e => e
So that means that fmap (*3)
has type fmap (*3) :: (Num a, Functor f) => f a -> f a
. Since (+5) :: Num d => d -> d
is the argument of that function, we see that f a ~ d -> d
. Or in a more canonical form: f a ~ (->) d d
. So that means that f ~ (-> d)
and a ~ d
. This holds since there is Functor
for (->) a
:
instance Functor ((->) a) where fmap = (.)
So we now have types:
fmap :: Num a => (a -> a) -> (a -> a) -> (a -> a)
fmap :: Num a => (a -> a) -> (a -> a) -> a -> a
fmap = (.)
(*3) :: Num a => a -> a
(+5) :: Num a => a -> a
1 :: Num e -> e
So that means that fmap (*3) (+5)
has type (->) a a
. We call this function with 1
, so that means that e ~ a
, so:
fmap :: Num a => (a -> a) -> (a -> a) -> a -> a
fmap = (.)
(*3) :: Num a => a -> a
(+5) :: Num a => a -> a
1 :: Num a -> a
So now we type checked the function, and we came to the conclusion that fmap = (.)
, so we have basically written:
(((.) (*3)) (+5)) 1
And now if we want to evaluate this, we get:
(((.) (*3)) (+5)) 1
-> (*3) ((+5) 1)
-> (*3) 6
-> 18
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