显式声明内联函数签名

explicitly declaring inline functions signatures

考虑此代码

open System.Runtime.CompilerServices


[<Extension>]
type Foo = 
    [<Extension>]
    static member inline classID (any : ^T) : ^U = 
        (^T : (member classID : Unit -> ^U) any)
    [<Extension>]
    static member inline parent (any : ^T) : ^U = 
        (^T : (member parent : Unit -> ^U) any)

let inline foo (tx : _) =
    tx.classID() + "!" + tx.parent().classID()

第一个问题,foo的签名是什么?

我的智能感知说它

'a -> string (requires member classID and member parent and member classID)

公平地说,充其量是模糊的,因为这里涉及 2 个隐式类型参数,并且它没有指定哪个类型需要哪个成员,但这可能是工具问题。

是否可以为这个函数写一个明确的签名,例如像这样:

let bar : 'a -> string = 
    fun _ -> ""

let [var] : [signature] = 
   fun [param] -> [result]

foo 的[签名]是什么?

(在 运行 时会有一个关于提取此签名的额外问题,但我会把它作为一个单独的问题)

下面是我如何使用显式类型注释来编写 foo

let inline foo (tx : ^T
    when ^T : (member classID : unit -> string)
    and ^T : (member parent : unit -> ^U)
    and ^U : (member classID : unit -> string)) : string =
    tx.classID() + "!" + tx.parent().classID()

所以,理论上,我想它的签名是:

(^T
    when ^T : (member classID : unit -> string)
    and ^T : (member parent : unit -> ^U)
    and ^U : (member classID : unit -> string)) -> string

不可能为bar写一个明确的签名,因为bar必须是内联的,而且只有函数可以内联,所以bar本身是不可能的。

这就是我在上面写“理论上”的原因。你不能在实际的 F# 代码中使用 foo 的签名,那么它真的有签名吗?这里的根本问题是 F# 中的静态解析类型参数(恕我直言)非常不稳定且记录不足,因此很难确定您的问题是否有任何真正正确的答案。