In this example from Learn you a Haskell, the author showed how to declare an instance of Applicative
for function ->r
instance Applicative ((->) r) where
pure x = (\_ -> x)
f <*> g = \x -> f x (g x)
Later on, he gave a concrete example
ghci> (\x y z -> [x,y,z]) <$> (+3) <*> (*2) <*> (/2) $ 5
[8.0,10.0,2.5]
I try to reason this snippet step by step
- Seeing
(+3) <*> (*2) <*> (/2)
asf <*> g <*> h
and thinking thatf <*> g <*> h
returns a function\x -> f x (g x (h x))
, I thought(+3) <*> (*2) <*> (/2)
returns a function\x -> x+3 (x*2 (x/2))
. But I can not do:t (+3) <*> (*2) <*> (/2)
in ghci, which raises this error
error:
• Occurs check: cannot construct the infinite type:
a1 ~ a -> a1 -> b
Expected type: (a -> a1 -> b) -> a1
Actual type: a1 -> a1
• In the second argument of ‘(<*>)’, namely ‘(/ 2)’
In the expression: (+ 3) <*> (* 2) <*> (/ 2)
- If
(+3) <*> (*2) <*> (/2)
does return a function\x -> x+3 (x*2 (x/2))
, how does it pattern match with the lambda function\x y z -> [x,y,z]
? (Actually I am still having some trouble to understand lambda functions except for the really basic simple ones.)