Pipe operator in Elixir is great, you can compose your functions naturally. However, there are times when you want to pipe the input to the second argument. How would you do that?


iex> sum_number = fn x, y -> x - y end  
iex> sum_number.(20,10)  
iex> 10 |> sum_number.(20)  
# Welp, this doesn't work as intended obviously

Initially, I thought I could curry the sum_number and 10 will be applied to the curried sum_number. Here is the desugared version of what actually happens when you do 10 |> sum_number.(20).

iex> 10 |> sum_number.(20)  
# sum_number(10, y) -> sum_number(10,20) -> -10
# Pipe always pipes the input to the first argument

***My initial thought is (wrong),
# sum_number(20, y) -> sum_number(20,10) -> 10

Obviously, you can solve this with

iex> 20 |> sum_number.(10)  
# sum_number(20, y) -> sum_number(20,10) -> 10

but my point is that there are certain times that you need behavior like in (***) i.e. you want the input (the left hand side of |>) to be piped to the second argument.


In Haskell, I can do something like this because Haskell has currying support. Elixir does not have built-in support for currying.

main = do  
    print $ (flip sumNumber 10) 20 
    -- flip will flip the arguments position, x y -> y x
    -- (flip sumNumber 10) gives out a function that takes another input

sumNumber :: Int -> Int -> Int  
sumNumber x y = x - y  

In Elixir, I could make use of & operator

iex> 10 |> (&sum_number.(20, &1)).()  

My example above is a little contrived. Here is another one,

|> transform_struct # this returns another struct
|> (&extract_something_from_struct(keyword, &1)).()
|> IO.puts # print extracted value

where extract_something_from_struct can be something like

def extract_something_from_struct(keyword, struct) do  
  # retrieve keyword value from struct