Currying in F#

Currying is a transformation process which converts a function with multiple arguments into a chain of embedded functions, each with single parameter. In F# function declarations are curried by default. Therefore you don’t usually need to curry functions. But even if this is an automatic transformation process it is helpful to understand why functions are used in this way.

 
Currying

The following example shows functions to sum two values. The first function has two parameters and the second function has only one parameter, a tuple with the needed values.

//create functions
let sum1(x,y) = 
    x+y

let sum2 x y = 
    x+y

//use functions
let x = sum1(2,3)
let y = sum2 2 3

let values = (2,3)
let z = sum1 values

 

Except of the syntax there are no visible differences between these two functions. Therefore we want to take a deeper look into the curried functions. Let’s start by looking at the function declaration:
val sum1 : int * int -> int
val sum2 : int -> int -> int

 
The first function takes a tuple and returns an integer. The second function instead gets an integer and returns a function which gets an integer and returns an integer. Therefore the function sum2, with the two parameters is transformed by default into a chain of single-parameter functions.

The following source code shows this sum function again and the resulting curried version of the function. In line 11 you see that it is possible to call the function with a single parameters and use the returning function to call it with the second parameter.

let sum x y = 
    x+y

let sum_curried = 
    fun x -> 
        fun y -> 
            x+y

let x = sum 2 3
let y = sum_curried 2 3
let z = (sum 2) 3

 
Partial application of arguments

Curried functions offer an easy way to create partial functions. I want to demonstrate this with the next example. Let’s say we want to implement a function which increases the given parameter by adding 3. Of course for this issue we may use our already implemented sum function. We know that the curried version of this function is called with one parameter and will return another function which needs the second parameter as input. Therefore it is possible to create the add function by using the sum function with parameter 3. The following source code shows an according example.

let sum x y = 
    x+y

let add3 = sum 3

let x = add3 2 

 
Partial application of arguments can be done for functions that take tupled arguments as well. But in this case an explicit lambda function is needed. The following example shows the implementation needed for the tupled function.

let sum(x,y) = 
    x+y

let add3 = fun x -> sum(x,3)

let x = add3 2 

 
Pipe operator and partial applications

At next I want to show you another example which uses curried functions. Within the next use case we want to implement a function which doubles up all values of a list. The following source code shows a possible implementation. The function double was created which doubles up a value. Furthermore the function doubleAll is implemented which maps the double function with the list values.

let double x = 
    2*x

let doubleAll values = 
    List.map double values

let originList = [1;2;3]
let newList = doubleAll originList

 
However I don’t like the doubleAll function because it does not add much value and only calls another function. Therefore it is also possible to implement the same solution by using List.map without the unnecessary doubleAll function. The following source code shows possible implementations.

let double x = 
    2*x

let originList = [1;2;3]

let newListA = List.map double originList

let newListB = (List.map double) originList

let newListC = originList |> List.map double

 
As you can see I have implemented three different ways to use the List.map function. This is possible because this function is curried. In general, partial application of curried functions is a useful technique. In practice I really like the possibility to call curried functions by using the pipe operator. If you compare the three implementations in the example above you will see that the third version which uses the pipe operator is the one which is most easy to read and understand.

 
Summary

In general, when programming in F#, you should prefer the curried format of functions. This will avoid needless parentheses and allow you to easily create partial application. Currying in combination with the pipe operator allow you to create very nice and clean source code.

Advertisements
Dieser Beitrag wurde unter .NET, F# abgelegt und mit , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

Eine Antwort zu Currying in F#

  1. Thata schreibt:

    Ia1a6ve been exploring for a bit for any high-quality aeirclts or blog posts in this sort of space . Exploring in Yahoo I ultimately stumbled upon this website. Studying this information So ia1a6m satisfied to express that I have a very just right uncanny feeling I came upon exactly what I needed. I so much without a doubt will make certain to dona1a6t overlook this site and give it a look regularly.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s