【问题标题】:How do I write this member constraint in F#?如何在 F# 中编写此成员约束?
【发布时间】:2011-06-09 08:10:36
【问题描述】:

对于一个类型

type Cow() =
    class
        member this.Walk () = Console.WriteLine("The cow walks.")
    end

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

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

在这种情况下,类型是推断出来的。我无法像这样显式地写一个对生物参数的约束

// 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()

我做错了什么?

【问题讨论】:

    标签: generics f#


    【解决方案1】:

    问题不是显式编写约束,而是语法不太好,您可以在参数上放置成员约束,然后以通常的方式调用该成员。 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)
    

    【讨论】:

    • 您能解释一下为什么要求以这种方式编写正文吗?不是所有的类型信息都已经存在于第二种方法中了吗?
    • 成员约束系统非常复杂,并且与名义类型系统分开,因此您不会免费获得名义成员调用语法。事实上,(^a : (member Walk : unit -> unit) creature) 不调用任何东西,它是一个模板,用于在编译时生成函数的(内联)类型特定实现。我想可以实现所需的统一语法,但 F# 团队从未预料到成员约束会变得如此流行,只打算将它们用于核心库,因此在这个版本中语法完全崩溃了(交叉手指)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    • 2017-12-18
    • 1970-01-01
    相关资源
    最近更新 更多