如何在F#中编写此成员约束?

Sha*_*bie 16 generics f#

对于一种类型

type Cow() =
    class
        member this.Walk () = Console.WriteLine("The cow walks.")
    end
Run Code Online (Sandbox Code Playgroud)

我可以编写一个方法来强制执行成员约束方法Walk

let inline walk_the_creature creature =  
    (^a : (member Walk : unit -> unit) creature)
// and then do
walk_the_creature (Cow())
Run Code Online (Sandbox Code Playgroud)

在这种情况下,推断出类型.我无法像这样明确地在creature参数上写一个约束

// Does not compile
// Lookup on object of indeterminate type based on information prior to this 
// program point. A type annotation may be needed...
let inline walk_the_creature_2 (creature:^a when ^a:(member Walk : unit -> unit)) =
    creature.Walk()
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

Ste*_*sen 25

它没有明确地写出问题的约束,而是语法不太好,你可以在参数上放置成员约束,然后以通常的方式调用成员.的身体walk_the_creaturewalk_the_creature2会在这里一样的:

let inline walk_the_creature_2 (creature:^a when ^a:(member Walk : unit -> unit)) =
    (^a : (member Walk : unit -> unit) creature)
Run Code Online (Sandbox Code Playgroud)

  • 成员约束系统非常复杂,与标称类型系统分离,因此您无需免费获得名义成员调用语法.事实上,`(^ a :(成员Walk:unit - > unit)生物)`不会调用任何东西,它是一个模板,用于在编译时生成函数的(内联)类型特定实现.我想可以实现所需的统一语法,但是F#团队从未预料到成员约束会变得如此受欢迎,仅仅意味着核心库,因此语法在这个版本中是完全破坏的(交叉指针). (11认同)