I took a break from the web and decided to work on something different, like F#. What I didn’t realize is how awesome F# has helped me understand LINQ in C# and Vice Versa.
I have read most of the blog, from the Edulinq series. This gave me insight to what is happening in LINQ, it’s to crunch lists of data. This sounds like something that F# does well.
Some of the structure threw me off of F#, like loops and if/else statements. But there are ways around this:
In order to have a traditional switch statement, or if/else for that matter, you should look into pattern matching:
match isDivisible with | true -> acc/item | false -> acc
This show how to switch between true and false. Pattern matching is more powerful than switch statements, however:
match list with | head -> (\* process one item \*) | tail -> (\* process the rest of the list \*) | \_ -> (\* oops something happened \*)
So for the simple example, this is matching pieces of a list. The first line you process the first item in the list, and the second line, you process the rest of the list. This pattern can help process a list super quickly.
So now that you have your branching methods, how can you loop and generate data? This is where [1 .. n] comes in. If you need to generate data, you can use this, but what if you need to generate a more complex set of data? Use an unfold:
Seq.unfold( fun(x) -> Some(x, x+1) ) 2 |> Seq.takeWhile (fun x -> x = 10)
The first line takes a function that generates a list from 2 to some number incrementing by 1. The second line stops generating numbers, once you get to 10. So after these 2 lines, it will generate an IEnumberable that will yield: [2,3,4,5,6,7,8,9,10]. It is important to note that this does not execute until you need to process the data later. Something we are fond of in LINQ with enumerables.
So this generates a list, how can we condense a list into one thing, like a Sum? Use a fold:
[1..10] |> Seq.fold(fun acc elem -> acc = acc + elem) 0
While you could use the Sum function, fold can do the same thing, and more. Fold takes in a set, [1..10], a function, and a starting value. The function has a signature of 2 parameters, the accumlator and each element it will loop through.
The neat thing with F# is that all Seq, or List or Array objects have these functions, more or less. All these functions do is loop through all the elements of a collection and execute the same function on each of the elements. The difference is what is returned from those values.
Map executes a function on each item of an array. Note this may change the element
Takes: a list, and a function that executes on every item in the list
Returns: The modified list
Much like Map, except it does not return a modified list, and is more for side effects.
Takes: a list, and a function that executes on every item in the list
Returns: unit, which basically means returns nothing (not null, it’s complicated)
Yes, there is a function called nth, which gives you that nth item, get it?
Takes: a list, and the index of the value you wanted
Returns: the element of that index. kinda like in c# array a[1] or elementAt
Reverses an list
Takes: a list
Returns: the reverse of the list
Gets the max number
Takes: a list
Returns: the maximum value of the array
Gets the sum of an list
Takes: a list
Returns: The sum of all the values
Smashes 2 arrays together
Takes: a list and another list
Returns: both lists put together
Creates a sequence, in case the [1..n] method doesn’t work. And for int64, it doesn’t
Takes: The number you want to count up to and a function to generate for each index
Returns: a list
These functions and techniques are the basics, and will help you write some F# that is useful. Not only that, I hope it helps give you a new perspective on LINQ, because they are basically the same thing. If you have an F#, or LINQ, function that is also useful, please throw them into the comments.