New F# developer, long time C# developer. As an exercise in learning F#, I'm working my way through Eric Lippert's series on graph coloring translating from his C# to F#. I'm currently working on part two.
The original C# is in the blog post - here's the F# translation so far - but it doesn't compile:
type BitSet = struct
val bits : int
private new(b) = { bits = b }
static member Empty = BitSet(0)
member this.Contains (item:int) = (this.bits &&& (1<<< item)) <> 0
member this.Add (item:int) = BitSet(this.bits ||| (1 <<< item))
member this.Remove (item:int) = BitSet(this.bits &&& ~~~(1<<<item))
member this.Bits = seq {
for item in 0..31 do
if this.Contains(item) then
yield item
}
end
This produces the very mysterious error "error FS0406: The byref-typed variable 'this' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions" from the definition of Bits:seq<int>.
Curiously, changing the keyword "struct" to "class" results in valid code. Coming from a C# perspective, this seems like nonsense, but I'm sure there's a valid reason behind it. The question is - how should I write the Bits function? What's the underlying F# principle that I need to understand for this to make sense?