'Upper and Lower Half of UInt16 in Enum?

I need to make an F# enum where the upper and lower bytes of the enum's value have meaning.

To make the code easily readable and maintainable in the future, I want to show each half of the uint16. Documentation refers to the number as the first 8 bits and the second 8 bits. Endianness is outside the scope of my question.

I have tried this, but it does not work.

type headers : uint16 =
   | firstHeader = (0 <<< 8) + (0)
   | secondHeader = (1 <<< 8) + (4)
   | thirdHeader = (2 <<< 8) + (10)
   | fourthHeader = (3 <<< 8) + (1)

The following works, but it obfuscates the number's meaning and introduces the possibility of calculating the composite number incorrectly.

type headers =
   | firstHeader = 0us
   | secondHeader = 260us
   | thirdHeader = 522us
   | fourthHeader = 769us

It does not need to be an enum, but I do need the same functionality (ie. being able to refer to the value as headers.firstHeader and get the underlying value let x = uint16 headers.firstHeader).

Does anyone know how to accomplish something like this?



Solution 1:[1]

You can't do this with an enum in F# because enum values must be literals. However, you could simply declare these as values within a module instead:

[<RequireQualifiedAccess>]
module headers =
    let firstHeader = (0 <<< 8) + (0)
    let secondHeader = (1 <<< 8) + (4)
    let thirdHeader = (2 <<< 8) + (10)
    let fourthHeader = (3 <<< 8) + (1)

The RequireQualifiedAccess attribute forces uses of the values to explicitly refer to headers, just like an enum (e.g. headers.firstHeader).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1