Search code examples
functionhaskelloperatorspointfree

Function application: Why is $ used here?


A while ago, I asked a question about $, and got useful answers -- in fact, I thought I understood how to use it.

It seems I was wrong :(

This example shows up in a tutorial:

instance Monad [] where
   xs >>= f = concat . map f $ xs

I can't for the life of me see why $ was used there; ghci isn't helping me either, as even tests I do there seem to show equivalence with the version that would simply omit the $. Can someone clarify this for me?


Solution

  • The $ is used here because it has lower precedence than normal function application. Another way to write this code is like so:

    instance Monad [] where
       xs >>= f = (concat . map f) xs
    

    The idea here is to first construct a function (concat . map f) and then apply it to its argument (xs). As shown, this can also be done by simply putting parenthesis around the first part.

    Note that omitting the $ in the original definition is not possible, it will result in a type error. This is because the function composition operator (the .) has a lower precedence than normal function application effectively turning the expression into:

    instance Monad [] where
      xs >>= f = concat . (map f xs)
    

    Which doesn't make sense, because the second argument to the function composition operator isn't a function at all. Although the following definition does make sense:

    instance Monad [] where
      xs >>= f = concat (map f xs)
    

    Incidentally, this is also the definition I would prefer, because it seems to me to be a lot clearer.