Home > database >  Constructor parameter validation code doesn't compile
Constructor parameter validation code doesn't compile

Time:10-05

I'm trying to write a simple abstract class in F# with some basic parameter validation:

[<AbstractClass>]
type Record(recordType: int16) =
    let recordType: int16 = recordType

    do
        if recordType < 0s then
            invalidArg (nameof recordType)

However, I'm getting an error on the last line: 'this if expression is missing an else branch.' I tried adding an else branch that just evaluates to null, but then the type system doesn't agree with my code. Am I doing something wrong? Should I be validating my arguments using some other method?

CodePudding user response:

The problem is that invalidArg requires a parameter name (which you've passed as nameof recordType as well as an error message, which you left off, and your if branch returns a function (string -> 'a as the return type is unknown/unreachable since the exception is thrown).

If you look at the docs for invalidArg, you see this: invalidArg parameter-name error-message-string. Your code is effectively like this:

// This is a function: string -> 'a (as it raises an exception, the return type is unknown)
let partialInvalidArg = invalidArg (nameof recordType)
if recordType < 0s then
    partialInvalidArg // You're returning a function, not unit, so the compiler complains

If you include the error message, the function is actually called in the branch, and this will compile fine:

[<AbstractClass>]
type Record(recordType: int16) =
    let recordType: int16 = recordType

    do
        if recordType < 0s then
            invalidArg (nameof recordType) "The recordType must be greater or equal to zero"
  • Related