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:
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:
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:
So now we can do this:
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:
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.
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 3 ways I can help you:
- Production-Ready Serverless: Join 20+ AWS Heroes & Community Builders and 1000+ other students in levelling up your serverless game.
- Consulting: If you want to improve feature velocity, reduce costs, and make your systems more scalable, secure, and resilient, then let’s work together and make it happen.
- Join my FREE Community on Skool, where you can ask for help, share your success stories and hang out with me and other like-minded people without all the negativity from social media.
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 :)