Considering the following record types:
type drCode1Body = {DrCode : byte ; Name : string ; Timestamp : DateTime ; Size : uint32 ; Options : byte}
type drCode2Body = {DrCode : byte ; LastBlock : byte ; BlockNumber : uint16 ; BlockSize : uint16 ; BlockData : array<byte>}
type drCode4Body = {DrCode : byte ; Name : string ; Timestamp : DateTime ; Options : byte ; Size : uint16 ; Data : array<byte>}
If I try to create instances like this (code snippets, not full code):
{DrCode = 1uy ; Name = name ; Timestamp = timestamp ; Size = size ; Options = options}
{DrCode = 2uy ; LastBlock = lastBlock ; BlockNumber = blockNumber ; BlockSize = blockSize ; BlockData = blockData}
{DrCode = 4uy ; Name = name ; Timestamp = timestamp ; Options = options ; Size = size ; Data = data }
It does not accept the first line to be valid.
Even though the size in the first line is a uint32 value.
It simply says “no assignment given for field ‘Data’.”
Changing the names of the parameters does not help either,
I tried this as well:
{new drCode1Body with DrCode = 1uy and Name = name and Timestamp = timestamp and Size = size and Options = options}
Then I get the following exception:
This expression has type drCode1Body but is here used with type drCode4Body
While I am clearly indicating what record type I want here.
What’s going on?
You can just write e.g.
to disambiguate when record field labels overlap.
(Effectively what happens is as F# starts reading the labels, it searches backwards for the first record type with those labels… once it sees DrCode and Name, it thinks ‘surely you mean drCode4Body!’… by providing diasmbiguation on the first field tag you steer the type-inference in the right direction.)
Code below compiles on F# 1.9.6.2: