【问题标题】:Define several members dynamically in class/interface using F#使用 F# 在类/接口中动态定义多个成员
【发布时间】:2026-01-21 06:25:01
【问题描述】:

我正在使用 F# 编写小程序,只是为了个人培训,得到了一些时间,我无法解决。

我在描述一些界面:

type IСalculations =
    abstract member Add : int * int -> int
    abstract member Subtract : int * int -> int
    abstract member Multiply : int * int -> int
    abstract member Divide : int * int -> int

如你所见,除了名字之外的成员签名都是一样的。

我能用 F# 做下一个吗(现在将是伪代码):

let names = [ "Add", "Subtract", "Multiply", "Divide" ];
let ICalculations = new interface;

foreach ( name in names ) {
    ICalculations[ name ] : int * int -> int
}

目的不是为每个成员重复签名int * int -> int

有可能吗?

【问题讨论】:

标签: dynamic types interface f#


【解决方案1】:

您不能在接口声明之后定义接口方法类型。 但是您可以定义例如 Dictionary,包含您的类型的函数:

open System.Collections.Generic    
type Ops = Add | Subtract | Multiply | Divide
let pseudoInterface = Dictionary<Ops, int * int -> int>()

// Then somewhere in your program you could define this "methods"
pseudoInterface.[Add] <- fun (i, j) -> i + j
pseudoInterface.[Subtract] <- fun (i, j) -> i - j // etc...

或者您可以为简洁起见为函数类型定义类型别名:

type Op = int * int -> int
type IСalculations =
    abstract member Add : Op    
    abstract member Subtract : Op
    abstract member Multiply : Op
    abstract member Divide : Op

【讨论】:

    【解决方案2】:

    声明接口的唯一语法是:

    // Interface declaration:
    [ attributes ]
    type interface-name =
       [ interface ]     [ inherit base-interface-name ...]
         abstract member1 : [ argument-types1 -> ] return-type1
         abstract member2 : [ argument-types2 -> ] return-type2
         ...
       [ end ]
    

    在你的伪代码的第二行:

    let ICalculations = new interface;
    

    您希望使用 let 绑定或等效项。 不幸的是,让绑定只将标识符与值或函数相关联,而不是与类型或接口相关联。 所以恐怕没有办法。 除了 F# 之外的其他函数式语言,例如 Idris,可以做到这一点。 如果您只是对重复 int*int->int 的冗长感到困扰,您可以定义一个类型别名,如下所示:

    module T =
      type Op = int * int -> int
    
    type IСalculations =
        abstract member Add : T.Op
        abstract member Subtract : T.Op
        abstract member Multiply : T.Op
        abstract member Divide : T.Op
    

    【讨论】: