Vasu Balakrishnan’s Blog

Archive for the ‘F#’ Category

F# |> operator

leave a comment »

 

As I was reading this blog, it made it clear to me the usefulness of currying, partial application forward pipe concepts of a functional program.

Look at the following lines of code in C#. If we don’t want to store intermediate results we have to write our algorithm in reverse order and with heavily use of brackets. The function we want to apply last has to be written first. This is not the way we think about it.

 
var list = new List<int> {4,2,6,5,9,3,8,1,3,0};
Console.WriteLine(Square(CalculateSum(FilterEven(list))));

 

The same can be written in F# as below. We describe the data flow in exactly the same order we talked about it.

 
let list = [4; 2; 6; 5; 9; 3; 8; 1; 3; 0] 
let square x = x * x
list 
    |> List.filter (fun x -> x % 2 = 0) // partial application 
    |> List.sum 
    |> square 
    |> printfn "%A" // partial application

 

Advertisements

Written by nbvasu

June 18, 2009 at 10:59 pm

Posted in F#

Learning F#

leave a comment »

Since I’ve started to use LINQ, I was interested to learn about Functional Programming. Its a programming paradigm that embraces functions as first class citizens, enables higher order functions, avoids mutable state, etc. The more I started to use in my projects, I began to appreciate the functional style of programming, and  that’s how I got me learn F#.

We have built a statistical module in C# to calculate mean, standard deviation, etc. I wanted to try implementing them in F#.

module stats =

    let sqr x = x * x
    let mean (data : vector)  = data |> Seq.average
    let max  (data : vector)  = data |> Seq.max
    let min  (data : vector)  = data |> Seq.min
    let range (data : vector) = max data - min data

    let avggain (data : vector) =
        data |> Seq.filter (fun x -> x > 0.0) |> Seq.average

    let avgloss (data : vector) =
        data |> Seq.filter (fun x -> x < 0.0) |> Seq.average
        
    let variance (data : vector) = 
        let mean = mean(data)
        (data |> Seq.sum_by(fun x -> sqr(x - mean))) / float (data.Length - 1)

    let stddev (data : vector) = sqrt(variance(data)) 
    let stddev3 (data : vector) = stddev(data) * sqrt(3.0)
    let stddev12 (data : vector) = stddev(data) * sqrt(12.0)

    let skew (data : vector) = 
        let mean = mean(data)
        let stddev = stddev(data)
        let sum = data |> Seq.sum_by(fun x -> ((x - mean) / stddev) ** 3.0)
        let fact = (float data.Length / float ((data.Length - 1) * (data.Length - 2)))
        sum * fact

    let kurtosis (data : vector) =
        let mean = data |> mean
        let stddev = data |> stddev
        let len = float data.Length
        let fact1 = len * (len + 1.0) / ((len - 1.0) * (len - 2.0) * (len - 3.0))
        let fact2 = 3.0 * Math.Pow((len - 1.0), 2.0) / ((len - 2.0) * (len - 3.0))
        let sum = data |> Seq.sum_by(fun x -> Math.Pow(((x - mean) / stddev), 4.0))
        sum * fact1 - fact2

 

Here is how you use them.

    let data = vector [0.20; -2.70; 1.59; 0.74; 0.31; 1.87]
    printfn "Input Data\n %A"  (data)
    printfn "Mean - %A"  (stats.mean data)
    printfn "Max - %A" (stats.max data)
    printfn "Min - %A" (stats.min data)
    printfn "Range - %A" (stats.range data)
    printfn "AvgGain - %A" (stats.avggain data)
    printfn "AvgLoss - %A" (stats.avgloss data)
    printfn "Variance - %A" (stats.variance data)
    printfn "StdDev - %A" (stats.stddev data)
    printfn "StdDev3 - %A" (stats.stddev3 data)
    printfn "StdDev12 - %A" (stats.stddev12 data)
    printfn "Skew - %A" (stats.skew data)
    printfn "Kurtosis - %A" (stats.kurtosis data)

    

Its pretty straight forward code. I could’ve done the same in C# and with LINQ it would be pretty much be the same number of Lines. The one thing I like in this implementation is pipe forwarding operator (|>) in F#. To me it makes it so much easier to read the code. I wish I could do that in C#.

 

Written by nbvasu

June 10, 2009 at 4:35 pm

Posted in F#