Sunday, February 8, 2009

F# – Functional Composition

I have created an example code in a previous blog entry to demonstrate the piping capabilities of F#:

let replace from tos list =
    List.map (fun item -> 
                if item = from then tos
                else item )
             list
        
let count list =
    List.length list
    
let printList list =
    List.iter (fun item -> printfn "[%s]" item) list
    
let abc = ["a";"b";"c"]
abc |> printList

abc |> replace "a" "k" |> count |> printfn "Number of items: %d"
abc |> replace "a" "k" |> printList
[a]
[b]
[c]
Number of items: 3
[k]
[b]
[c]

This is a form of code we got used to in C-like languages: we have a function and we have arguments. What can we do if we don’t want to specify the arguments for a function? We can use functional composition.

let count =
    List.length

let replace from tos =
    List.map (fun item ->
                if item = from then tos
                else item)

let printList =
       List.iter (fun item -> printfn "[%s]" item)
       

let abc = ["a";"b";"c"]
abc |> printList

let nrOfItems =
    replace "a" "k"
    >> count
    >> printfn "Number of items: %d"
    
let printReplace =
    replace "a" "k"
    >> printList

abc |> nrOfItems
abc |> printReplace
[a]
[b]
[c]
Number of items: 3
[k]
[b]
[c]

You can omit the parameter of the function and you can specify that at calling time. Code is more readable, maintainable.

The operator specification for functional composition (>>) is:

let (>>) f g x = g(f(x))

The operator specification for pipeline (|>) is:

let (|>) x f = f x