F# and picking a method based on an if statement

I actually saw this first in SICP, but then proceeded to see if F# can do this. Basically it’s an if statement that selects a method to use based on a clause, and then evaluates using two parameters.

  let add x y = x + y
  let sub x y = x - y
  (if 0 = 0 then add else sub) 1 2

As you can see, the parameters stay the same but the actual method called doesn’t. The way it’s written, it evaluates to:

  add 1 2

However, were I to switch the 0 = 0 to 0 = 1 then:

  sub 1 2

Not sure how this would apply to real life, but knowing is the first step.

F# and assigning operators as methods

Once again I have fallen back on F# as the main language of interest. At least until I pick the next one to replace it. Not like I’m wishy washy or anything.

One of the more interesting things about languages like Scheme or Lisp is that nothing is sacred. You can assign characters to methods, and this is possible in f# also.

Here’s an example of a “default” way of defining %% as adding two numbers together.

  let (%%) x y = x + y
  // 1 %% 2 results in 3

As you can see, the %% just looks like a typical operator method. However, it can be changed so that it is actually before the arguments:

  let (!%%) x y = x + y
  // !%% 1 2 results in 3

For anyone who has used Lisp, this should look familiar. It is called Prefix Notation.

Now for something a little more interesting: Take the List.map method. It basically takes a list and applies a method to every member to create a new list. For the C# people, it’s equivalent to someList.Select(x => method(x)). Say you wanted to create a method that just takes a list and “maps” a method to add one to each item.

  let result = List.map (fun y -> y + 1) [1;2;3;]

Pretty simple. Now what if you want to make this a method that takes in a list and applies the same method above to each item?

  let addOne x = List.map (fun y -> y + 1) x
  // addOne [1;2;3] results in 6

Pretty simple again. Now in one more step you can assign operators to do the same:

  let (!+) x = List.map (fun y -> y + 1) x
  // !+ [1;2;3] results in 6

Now I realize this may seem trivial, but it’s actually quiet useful when you start talking about Domain Specific Languages since this allows methods to use non Alpha names.