Search code examples
haskellfunctional-programmingcurryingpartial-applicationoperator-sections

Partial Application with Infix Functions


While I understand a little about currying in the mathematical sense, partially applying an infix function was a new concept which I discovered after diving into the book Learn You a Haskell for Great Good.

Given this function:

applyTwice :: (a -> a) -> a -> a
applyTwice f x = f (f x)

The author uses it in a interesting way:

ghci> applyTwice (++ [0]) [1]  
[1,0,0]
ghci> applyTwice ([0] ++) [1]
[0,0,1]

Here I can see clearly that the resulting function had different parameters passed, which would not happen by normal means considering it is a curried function (would it?). So, is there any special treatment on infix sectioning by Haskell? Is it generic to all infix functions?


As a side note, this is my first week with Haskell and functional programming, and I'm still reading the book.


Solution

  • Yes, you can partially apply an infix operator by specifying either its left or right operand, just leaving the other one blank (exactly in the two examples you wrote).

    So, ([0] ++) is the same as (++) [0] or \x -> [0] ++ x (remember you can turn an infix operator into a standard function by means of parenthesis), while (++ [0]) equals to \x -> x ++ [0].

    It is useful to know also the usage of backticks, ( `` ), that enable you to turn any standard function with two arguments in an infix operator:

    Prelude> elem 2 [1,2,3]
    True
    Prelude> 2 `elem` [1,2,3] -- this is the same as before
    True
    Prelude> let f = (`elem` [1,2,3]) -- partial application, second operand
    Prelude> f 1
    True
    Prelude> f 4
    False
    Prelude> let g = (1 `elem`) -- partial application, first operand
    Prelude> g [1,2]
    True
    Prelude> g [2,3]
    False