Friday, December 23, 2011

Hacking Type Classes in F#

Recent FPish FPish discussion focused on some hacks available in F# to write code that resembles using Haskell type classes. I particularly enjoyed the comments by Gustavo Leon and Loic Denuziere.

To cut the long story short, before compiling to .NET F# expands methods delcared inline and does overload resolution. This was intended to support flexible operator overloading, but opens up the door for interesting hacks. Even code that generalizes over higher kinds and therefore cannot exist at .NET level can with these hacks exist at the inline F# level.

Although these remain hacks (ugly code, unreadable inferred types, fragility to changes when type inference stops working, difficulty in scaling to more complicated examples), I cannot help but enjoy it. Here is a writeup that infers JSON serialization automatically over lists at the inline level:

4 comments:

  1. It's fairly elegant still... I wish I was imposed to do idiomatic F# all the time.

    Type Classes are clearly one of the most requested feature, let's hope they'll roll their sleeve yet again and deliver there as well... F# 3.5??

    ReplyDelete
  2. That indeed would be very nice :) Or perhaps someone will come up with an F# contender language that would work on .NET but give more priority to either TC or a proper module system, even at at the cost of other things.

    ReplyDelete
  3. Hi Anton!

    Could you blog about how exactly your sample works? I read the stuff at Gustavo's blog, but your sample looks simpler and would be a great explanatory tool!

    ReplyDelete
  4. Thanks for your interest, Bryan. Erm, can you make the question a bit more specific? The general answer would be that the sample works by using method overload resolution rules during the F# inline expansion phase. So, for example, ToJson applied to a list of Person objects resolves to `ToJson(_: Json, x: list<_>)` which in turn calls another `ToJson` that resolves to `ToJson` method on Person.

    ReplyDelete