How do I define a function in F# f
that only accepts an argument x
which is restricted to be of type int32
or int64
?
Here's a way is to restrict it at compile time. First create the generic version of your function:
let inline twice x = x + x
Then restrict it for the desired types by using overload resolution and static member constraints:
type T = T with
static member ($) (T, x:int ) = twice x
static member ($) (T, x:int64) = twice x
let inline restrictedTwice x = T $ x
Tests:
restrictedTwice 4 //val it : int = 8
restrictedTwice 5L //val it : int64 = 10L
restrictedTwice 5u // doesn't compile
If you can live with defining the function as a class method, you can use normal .NET method overloading:
type Foo =
static member Bar (x : int) = sprintf "32-bit integer: %i" x
static member Bar (x : int64) = sprintf "64-bit integer: %i" x
FSI examples:
> Foo.Bar 42;;
val it : string = "32-bit integer: 42"
> Foo.Bar 42L;;
val it : string = "64-bit integer: 42"
If you need the function to be a let-bound function, you can't use method overloading. Instead, you can define a discriminated union that constrains the input options to either int
or int64
:
type DUInt =
| NormalInt of int
| BiggerInt of int64
You should probably come up with some better names, but I chose to avoid Int32
and Int64
because it would make the code difficult to read, as the System
namespace also defines these names as types.
With this discriminated union, you can write a function that take a value of that type as input:
let foo = function
| NormalInt x -> sprintf "32-bit integer: %i" x
| BiggerInt x -> sprintf "64-bit integer: %i" x
This function has the type DUInt -> string
.
FSI examples:
> foo (NormalInt 42);;
val it : string = "32-bit integer: 42"
> foo (BiggerInt 42L);;
val it : string = "64-bit integer: 42"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With