When we have the expression:
(fmap . fmap) function nested_functor
I would expect it to translate to something like
fmap (fmap function nested_functor)
Though it surprisingly seems to behave as
fmap (fmap function) nested_functor
Why?
Chris Martin
30.9k12 gold badges83 silver badges142 bronze badges
asked Dec 8, 2016 at 18:17
Pedro Rolo
30.3k13 gold badges63 silver badges95 bronze badges
1 Answer 1
Well, just look at the definition of (.):
(f . g) x = f (g x)
So,
(fmap . fmap) function = fmap (fmap function)
Adding an additional argument at the end doesn't really change the equation -- just makes it more specific.
(fmap . fmap) function nested_functor = fmap (fmap function) nested_functor
(N.B. function application is left associative, so f x y means (f x) y.)
answered Dec 8, 2016 at 19:11
Daniel Wagner
156k10 gold badges231 silver badges392 bronze badges
Sign up to request clarification or add additional context in comments.
2 Comments
Pedro Rolo
Thank you! My confusion was due to thinking through this as if function application would be right associative, and the mess was due to that (->) associating to the right in the type signatures... I am now finding it funny that functional application in type declarations has a different associativity than in the expressions themselves.
David Young
@PedroMorteRolo It is sort of symmetrical that way. With it set like it is, you can have no parentheses in an application of
fn to 'two' arguments as fn x y and no parentheses in the corresponding type signature for fn :: Int -> Int -> Bool (for example). If they associated in the same way (regardless of which way that is), one of those two things would need parens and the other wouldn't.Explore related questions
See similar questions with these tags.
lang-hs
a->b->cis the same asa->(b->c). Build from here.f x yis the same as(f x) y. (f :: a->(b->c),x :: a,y :: b)