3 Things I wish I knew about F# before I started that big project

Hey everyone, today I wanted to share some insights I’ve gained while learning F# over the past few weeks/months/years (it’s been an on-again, off-again relationship). I love F# but coming from a land of large C# projects, there are some edge cases where you may find yourself tripped up if you’re relatively new to F#.

Bitshift enumerations are not supported

Coming from C#, more than a few of my enumerations followed the pattern of:

enum myEnum = 
   a = 1 << 0,
   b = 1 << 1,
   c = 1 << 2,
   d = 1 << 3

Unfortunately, using bitshift operators within a union/enumeration declaration in F# is not supported. You can however accomplish the same thing using a manually generated bit field as shown below. Easy, but slightly less maintainable.

Type myEnum = 
   a = 0b00001
   b = 0b00010
   c = 0b00100
   d = 0b01000

Null Refs will still plague you

One of the things that quickly becomes apparent when integrating your F# app into a C# ecosystem is that while F# does have a native NULL type, it will still crash spectacularly when dealing with null C# types. Consider the following:

match SomeObj.Prop with  //nullref
   | condition A -> ...
   | condition B -> ... 

Solution? Wrap your questionable calls to C# objects in a ‘toOption’ call

let toOption = function
   | null -> None
   | object -> Some

then you can use it like so..

let myVal = toOption Someobj.Prop
match myVal with
    | Some -> ...
    | None -> ...

Presto! No more null-ref worries in your elegant F# code. Also, you avoid the need for constant “if x <> null then …”.

Serialization…

One of the great things about F# is the ease of record creation. Dreams of serializing these records and sending them across the wire to your web apis can quickly be shattered when you notice all your JSON objects serialized with @suffixes. What gives? F# record members are treated like C# Fields. Their underlying fieldname is serialized by most default .NET serializers resulting in something like the following..

type myRecord {
   Name : string;
   Age:  int;
   Exp:  int;
}

being serialized as:

{ "Name@":"Gandolf", "Age@":"225", "Exp@":"15" }

Fortunately,there’s JSON.NET to the rescue! No, you won’t have to re-write your serialization logic or anything. Simply add the following attributes to your type and you’re done! The rest will be handled auto-magically.

[<CLIMutable>]
[<JsonObject(MemberSerialization=MemberSerialization.OptOut)>]

That’s all for now folks but stop by in the future as I slowly begin to wake from my stupor and flesh out this blog/site.

Cheers