使用F#在类/接口中动态定义多个成员

时间:2015-12-19 15:06:41

标签: dynamic types interface f#

我正在使用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

有可能吗?

2 个答案:

答案 0 :(得分:5)

在接口声明后,您无法定义接口方法类型。 但是你可以定义例如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

答案 1 :(得分:1)

声明接口的唯一语法是:

// 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-&gt; 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