Search code examples
haskellfunctional-programmingoperatorsoperator-precedencefunction-composition

Haskell Function Composition (.) vs Function Application ($)


I'm going through this source code for learning.

On line 81 I see the following code:

MaybeT . fmap Just $ locked .= False

I was puzzled by the use of the function composition so I loaded it in my repl and replaced it with function application

MaybeT $ fmap Just $ locked .= False

I'm very surprised these two pieces of code give the exact result.

Control.Monad.State.Class.MonadState Game m => MaybeT m ()

In fact, I can understand how function application ($) is producing this result but I'm floored as to how function composition (.) is producing this result. The signatures of these two functions are different and I think they should clearly produce different results if one replaces the other.

:t (.) :: (b -> c) -> (a -> b) -> a -> c
:t ($) :: (a -> b) -> a -> b

Can someone explain to me why the ($) and (.) are interchangeable in this case.


Solution

  • . has a higher precedence than $:

    > :info ($)
    ($) :: (a -> b) -> a -> b   -- Defined in ‘GHC.Base’
    infixr 0 $
    > :info (.)
    (.) :: (b -> c) -> (a -> b) -> a -> c   -- Defined in ‘GHC.Base’
    infixr 9 .
    

    So a $ b $ c $ d is a $ (b $ (c $ d)), but a . b . c $ d is (a . (b . c)) $ d.