F# — Use Discriminated Unions instead of class hierarchies

When you con­sid­er the age old prob­lem of rep­re­sent­ing dif­fer­ent shapes (cir­cle, tri­an­gle, square, rec­tan­gle, etc.) my OO fed devel­op­er brain nat­u­ral­ly jumps to a class hier­ar­chy along the line of:

image

This is per­fect­ly fine and legit, but it’s not the only way to approach things. Since I’ve been on a more var­ied diet of pro­gram­ming par­a­digms I’m much more open to the idea of using F#’s dis­crim­i­nat­ed unions to rep­re­sent hier­ar­chi­cal data.

Dis­crim­i­nat­ed union is a fun­da­men­tal type in func­tion pro­gram­ming, and for C# devel­op­ers, think of it as an Enum with strong­ly typed names where the names don’t have to be of the same type. Using dis­crim­i­nat­ed unions, you can rewrite the above code as:

image

And to test it, let’s cre­ate some shapes and work­out their respec­tive areas:

image

Was that more dif­fi­cult than its C# coun­ter­part? Not at all, in fact, I’ve lit­tered the F# code with com­ments and still end­ed up with near half as much code! Check out my solu­tion for project euler prob­lem 54, a work­ing pok­er hand eval­u­a­tor in 100 lines of code , pret­ty sweetSmile

Closing thoughts…

That said, class hier­ar­chies are great at mod­el­ling real world enti­ties and they allow you to cap­ture com­mon­al­i­ties and shared behav­iours, if done cor­rect­ly they can remove dupli­cat­ed code and reduce defects.

Dis­crim­i­nat­ed unions on the oth­er hand, are a great fit for hier­ar­chi­cal data struc­tures such as bina­ry tree, and for small hier­ar­chies it requires lit­tle over­head in set­ting them up so it can give you a nice pro­duc­tiv­i­ty boost.

Whilst I’m not sug­gest­ing that you should start con­vert­ing all your class hier­ar­chies to dis­crim­i­nat­ed unions, I think there is a lot of val­ue in hav­ing it in your tool­box nonethe­less. The more tools you have at your dis­pos­al the bet­ter, being able to use the right tool for the right task beats ham­mer­ing a screw in my opin­ion!