Reputation: 432
In the example below, I want every uint64 to be allowed except zero.
type Foo =
| Foo of uint64
let foo = Foo(5UL) // OK
let bar = Foo(-1) // Compiler error
let bad = Foo(0UL) // I want this to be a compiler error
Upvotes: 3
Views: 197
Reputation: 982
To the best of my knowledge, you can't directly place bounds on the values (if someone else knows otherwise, please do let us know). I think that is something referred to as 'dependent types', which I don't believe F# supports, at least not currently.
I'm guessing you're already well aware of the following, but for the sake of anyone else taking a look, I'll discuss how you might handle this at runtime: The easiest way to do this I believe would essentially be to make the type private and expose only a getFoo function that does custom validation at that time. Depending on what you want, you would either wrap it in an option or throw an exception when the wrong number is passed in. E.g.
type private FooWithException =
| Foo of uint64
let getFooWithException (x: uint64) =
if x = 0 then
failwith "x was zero"
else
Foo x
or
type private FooOption =
| Foo of uint64 option
let tryGetFoo (x: uint64) =
if x = 0UL then
None
else
Some(x)
You may also find this page at F# for Fun and Profit useful.
Upvotes: 4