Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Evaluation of expression fmap (*3) (+5) 1

Tags:

haskell

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
like image 512
Šefčíková Jana Avatar asked Mar 10 '18 18:03

Šefčíková Jana


1 Answers

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
like image 113
Willem Van Onsem Avatar answered Nov 15 '22 09:11

Willem Van Onsem