【问题标题】:F# module extension vs type entensionF# 模块扩展与类型扩展
【发布时间】:2011-05-20 22:09:28
【问题描述】:

如果我想为浮点数组定义一个扩展方法,比如标准偏差,是在数组模块上使用模块扩展还是在 float[] 类型上使用扩展更好? 喜欢:

module Array =
   let std (arr: float[]) = ...

type float ``[]`` with 
    member this.std = ...

如果我将类型扩展作为后者,std 是否只计算一次或每次使用它?

而且,后者的正确格式是什么,显然type float ``[]`` with 不符合...谢谢。

【问题讨论】:

    标签: f#


    【解决方案1】:

    在这种情况下,您无法定义类型扩展,因此问题没有实际意义 - 您必须使用 Array 模块的扩展。无法定义类型扩展的原因是在 F# 中,类型扩展必须完全镜像类型定义,因此您可以在泛型 'a list 类型上定义类型扩展,但不能在构造类型 @987654323 上定义类型扩展@。同样,您可以在(模拟的)泛型数组类型上定义扩展方法

    'a ``[]``
    

    但不在构造数组类型上

    float ``[]``
    

    这种行为与 C# 不同,C# 可以在构造的泛型类型上编写扩展方法。

    【讨论】:

    • @Daniel - 我没有。但是,我认为 F# 的行为确实有意义 - 为什么类型扩展不应该镜像类型定义?构造的泛型类型的实例上的方法取决于其类型参数,这似乎不奇怪吗?
    • @kvb:是的,但在泛型接口上似乎很有意义。例如,string Join(this IEnumerable<string> parts) 似乎是合理的。
    • 我认为 C# 和 F# 扩展功能在概念上是不同的,它们的语法不同。 F# 强调类型定义的扩展,而 C# 扩展仅作为静态方法实现,并且确实可以这样调用(第一个参数标记为“this”)。因此,如果您熟悉 C# 扩展,那么您可以重载“this”参数是完全合理的。而且您倾向于将它们视为具有实例语法的静态方法。
    • @Daniel - 我认为两种方式都有很好的论据,我只是声称 F# 的方法不一定有缺陷。我认为考虑到 F# 中模块的不错替代方案,这一点尤其正确。
    • 既可以在 F# 中使用 C# 扩展方法,也可以在 F# 中创建 C# 可使用的 C# 样式的扩展方法。如果 C# 风格的扩展方法在 F# 中也可以使用(我似乎无法让那部分工作),那么可能可以按照您的意愿进行操作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    • 2020-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-04
    相关资源
    最近更新 更多