I'm writing a library¹ in F# that provides some bitwise operations, and I want to make sure as many of my functions as possible are inline
let bindings with static type parameters (this allows me to write one function and use it for int16
, int32
, and maybe even bignum
with little overhead). This route will certainly fail to work at some point. Some of the functionality provided by said library is somewhat complicated.
¹Note: I'm aware of the issues of exposing inline let bindings via a public interface.
However, I want to stretch this to the furthest extent it can go. Right now, I'm trying to write the population count algorithm in this form, and I'm facing a problem. I'm not sure how to encode the masks, e.g. 0x3333...
, that appear in these algorithms. I can get around shift constants and similar using some extra bit trickery.
Is there any trick I can use, whether via F#'s type inference and static type parameters, or via bit-twiddling, to write the algorithm the way I want? Is there any way I can encode these sorts of constants in the statically generic function?
A more vague question: are there some specific things I can rely on to utilize static type parameters to their fullest, especially in the context of numerics? For example, I heavily use GenericOne
and GenericZero
. Are there more things like this, that I might have missed?