多种类型的F#功能类型注释

Tal*_*age 3 generics f# functional-programming

我正在尝试定义一个"准通用"函数.我不希望它完全是通用的,我希望它只适用于"整数"类型(即byte,sbyte,int16,uint16,int,uint32,int64,uint64,bigint).

如何将它放入函数定义的类型注释中?为了澄清,我将如何重写以下代码以实际工作(仅使用3种类型,可能不会失去泛化):

let square (x: int|int64|bigint) =
    x * x
Run Code Online (Sandbox Code Playgroud)

The*_*ght 7

首先,在运行时使用标准.NET泛型无法解决此类型约束.

F#允许您通过在编译时解析它们并插入适当的内联函数调用来表达有限形式的此类约束.这使用了静态解析的类型参数.

对于你所描述的情况来说,这很简单,你可以写:

let inline square x = x * x
Run Code Online (Sandbox Code Playgroud)

这适用于'T具有*运算符定义的任何类型.

您还可以显式应用特定的静态/成员约束,但这需要更复杂的语法,例如

let inline id item =
    ( ^T : (member Id : int) (item))
Run Code Online (Sandbox Code Playgroud)

此示例函数将在任何公开Id类型属性的类型上运行int.


更新:根据您描述的特定用例,您确实是类型类.那些在F#中并不存在(除了一些硬编码的例子),但你可以使用标记类型和成员约束来模拟它们,这是一个例子:

type Marker =
    |Marker

    static member Multiply (marker : Marker, numX : int, numY : int) =
        numX * numY
    static member Multiply (marker : Marker, numX : int64, numY : int64) =
        numX * numY

let inline multiply x y =
    ((^T or ^U) : (static member Multiply : ^T * ^U * ^U -> ^S) (Marker, x, y))

multiply 5 7
multiply 5L 7L
Run Code Online (Sandbox Code Playgroud)

请注意,这允许您指定要允许该功能的确切类型.