I have an enum type with the flags attribute:
[<Flags>]
type StatusWord =
| DATAPROCESS = 0b0000000001
| ERRORPRESENT = 0b0000000010
| CHECKSUMERROR = 0b0000000100
| PACKETSIZEERROR = 0b0000001000
| TIMEOUT = 0b0000010000
| DONOTRETRY = 0b1000000000
and during some data initialization, I have a uint16
value I want to convert to the enum's type, StatusWord
, so I can compare it's properties:
let value: uint16 = 0b1000001001us
let flags: StatusWord = StatusWord value
but, as you might be able to guess, this code doesn't compile; the conversion isn't available. Likewise, I also can't do explicit casts, eg. value :> StatusWord
or value :?> StatusWord
. This is a simple task in C#, so I'm having trouble figuring out why I can't do it in F#.
So, two things you have to worry about. One (which I think you already realize) is that your underlying enum type is int32, and your value is uint16, so a conversion will need to happen somewhere. Two, you have to construct the enum type.
StatusWord looks like a constructor (similar to a union case member), but it's not. So here are two ways to do it with your uint16 value, and a third way to do it which is much better for readability, if you can do it that way.
let value = 0b1000001001us
// use F# enum operator
let flags1 = enum<StatusWord> (int value)
// use static Enum class
let flags2 = Enum.Parse(typeof<StatusWord>, string value) :?> StatusWord
// do bitwise stuff, of course now the compiler knows what you're doing
let flags3 = StatusWord.DATAPROCESS ||| StatusWord.PACKETSIZEERROR ||| StatusWord.DONOTRETRY
Because there are multiple ways, I had to refresh my memory, which I did at
https://fsharpforfunandprofit.com/posts/enum-types/
which is highly recommended reading (that article and the rest of that blog - it's how many people learn F#).