If your have a type that represents a collection of values, adding a custom indexer gives you a natural way to index directly into the object using the .[ ] operator.
Take this simple Calendar class for instance, which keeps a map (F# equivalent of a Dictionary<TKey, TValue>) of notes against DateTime values:
By adding a custom indexer here I’m now able to write code like this:
Also, as you may have noticed already, F# allows you to use non-integer parameters in your indexer! In this case, I’m using a tuple of int * string * int. You can use this indexer from your C# code too:
That’s pretty cool, but we can go a step further by allowing you to use slicers on our types too. To allow users to get all the notes associated with a range of years, e.g. from 1999 to 2009, let’s add a slicer:
So now we can do this:
Pretty awesome, right? But what if we want to refine our search criteria even more and let you specify a year range as well a range of months, e.g. get me all notes for April/May/June in the years 1999 to 2009. Thankfully, F# lets you define a two-dimensional slicer too:
This two-dimensional slicer allows me to query the calendar with a year range as well as a month range:
As you can see, indexers and slicers give the consumers of your code a much more intuitive way to interact with the data encapsulated in your type. Keep in mind though, that F# does not allow you to add slicer with more than two dimensions, but I think two-dimensional slicers should be good enough for most day-to-day requirements.
Swapped out my verbose optional argument handling with defaultArg as Arseny Kapoulkine pointed out in the comments.
4 thoughts on “F# – Adding custom indexer and slicer to your type”
Thanks, this is useful.
Your method of handling optional arguments is quite verbose, defaultArg will do just fine (i.e. let lbYear = defaultArg lowerBoundYear DateTime.MinValue.Year)
Arseny – Thanks for the feedback, defaultArg had completely skipped my mind when I put the example together!
Pingback: F# equivalent of C#’s Object Initialization syntax | theburningmonk.com
Just what I wanted to know! Thank you :)