如何创建只接受int32或int64的函数

时间:2016-02-10 07:54:02

标签: f#

如何定义F#f中仅接受限制为xint32类型的参数int64的函数?

2 个答案:

答案 0 :(得分:7)

这是一种在编译时限制它的方法。首先创建函数的通用版本:

let inline twice x = x + x

然后使用重载决策和静态成员约束将其限制为所需类型:

type T = T with
    static member ($) (T, x:int  ) = twice x
    static member ($) (T, x:int64) = twice x

let inline restrictedTwice x = T $ x

试验:

restrictedTwice 4  //val it : int = 8

restrictedTwice 5L //val it : int64 = 10L

restrictedTwice 5u // doesn't compile

答案 1 :(得分:4)

重载

如果您可以将函数定义为类方法,则可以使用常规的.NET方法重载:

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示例:

> Foo.Bar 42;;
val it : string = "32-bit integer: 42"
> Foo.Bar 42L;;
val it : string = "64-bit integer: 42"

受歧视的工会

如果您需要将函数作为let-bound函数,则不能使用方法重载。 Instead, you can define a discriminated union将输入选项限制为intint64

type DUInt =
| NormalInt of int
| BiggerInt of int64

你应该想出一些更好的名字,但我选择避免使用Int32Int64因为它会使代码难以阅读,因为System命名空间也定义了这些名称为类型

使用这种区分联合,您可以编写一个将该类型的值作为输入的函数:

let foo = function
    | NormalInt x -> sprintf "32-bit integer: %i" x
    | BiggerInt x -> sprintf "64-bit integer: %i" x

此函数的类型为DUInt -> string

FSI示例:

> foo (NormalInt 42);;
val it : string = "32-bit integer: 42"
> foo (BiggerInt 42L);;
val it : string = "64-bit integer: 42"