F# – Adding custom indexer and slicer to your type

Yan Cui

I help clients go faster for less using serverless technologies.

Indexer

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:

image

By adding a custom indexer here I’m now able to write code like this:

image

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:

image

One-Dimensional Slicer

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:

image

So now we can do this:

image

Two-Dimensional Slicer

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:

image

This two-dimensional slicer allows me to query the calendar with a year range as well as a month range:

image

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.

Update 2011/11/08:

Swapped out my verbose optional argument handling with defaultArg as Arseny Kapoulkine pointed out in the comments.


 

Whenever you’re ready, here are 4 ways I can help you:

  1. If you want a one-stop shop to help you quickly level up your serverless skills, you should check out my Production-Ready Serverless workshop. Over 20 AWS Heroes & Community Builders have passed through this workshop, plus 1000+ students from the likes of AWS, LEGO, Booking, HBO and Siemens.
  2. If you want to learn how to test serverless applications without all the pain and hassle, you should check out my latest course, Testing Serverless Architectures.
  3. If you’re a manager or founder and want to help your team move faster and build better software, then check out my consulting services.
  4. If you just want to hang out, talk serverless, or ask for help, then you should join my FREE Community.

 


4 thoughts on “F# – Adding custom indexer and slicer to your type”

  1. 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)

  2. Arseny – Thanks for the feedback, defaultArg had completely skipped my mind when I put the example together!

  3. Pingback: F# equivalent of C#’s Object Initialization syntax | theburningmonk.com

Leave a Comment

Your email address will not be published. Required fields are marked *