Tuesday, April 29, 2008

Aventures in F# - words is all you need

F# let's you specify the same thing in different styles - depending on your likings (clarity, purity, style, compactness, problem-domain-specific) you my choose the appropriate expression.

For example: Assume we have a list of numbers and want to transform them in a certain way, e.g. we want to square them.

1. generate a list of numbers

let numbers = [for i in 1..10 -> i];;

Now we have different options to reach our goal, i.e. transforming the elements of the list to be equal to their respective square, i.e. i -> i * i

The first way to do this is to generate the set with squared numbers.
let sqnumbers = [for i in 1..10 -> i * i];;
While it solves the problem, it was not exactly what I was looking for.

So we define a function that takes an integer list as input and generates the appropriate output list by taking each element squaring it and appending it to the output list.
Let sqfunc be this function.

One way of calling sqfunc is: sqfunc numbers;;

But we could also use F#'s incredible pipelining operator >
which would result in: numbers > sqfunc;;
The operator matches perfectly the way of reading it, i.e. "put numbers into the pipeline component sqfunc" - Nice
So If we were to compute the fourth power of our numbers list we could write:
numbers > xfunc > xfunc;;

The pipeline operator is nothing but syntatctic suggar, being defined as:
let (>) x f = f x
where x is the input to apply the function f on.

Since we work on lists, we may also use the map function defined on list types. The map function takes as input a function that transforms elements of an input list. Therefore we may write
List.map (fun x -> x * x) numbers;;

This exhibits F#'s anonymous function values - so much like a C# delegate type as an input parameter to a function List.map.

Thursday, April 24, 2008

Adventures in F#

Adventure 1: Reversing an integer list

let rec ReverseList (l: int list) =
 match l with
 ¦ H::T -> (ReverseList T) @ [H]
 ¦ [] -> []

The code is quite simple. It does the following:
  1. define a recoursive function (rec keyword) on integer list argument
  2. use pattern matching (match with) on the argument l to decompose l into a head and a tail. The head is the head (first) element of l and tail is the remainder of l.
  3. use this knowledge to call itself recoursively
  4. It is checked whether l consists of a head H and a tail T, if yes, then ReverseList calls itself with T (the list consisting of the tail of l, i.e. l without the head element) and concatenates (@ operator) the result with the list consisting of the headelement ([H])
  5. if the input argument l is the empty list ([]), then ReverseList exits by returning the empty list.