在F#接口中实现GetSlice切片

时间:2016-11-30 10:54:27

标签: arrays multidimensional-array interface f# functional-programming

F#支持“切片表达式”,例如,对于传统的一维数组myArray,允许使用myArray.[3 .. 5]等表达式。根据例如F#4.0语言规范(第6.4.7节),这是通过在适当转换参数后调用GetSlice方法实现的。这也适用于多维数组。但是,我在定义在二维情况下实现它的接口时遇到了一些麻烦。

我所做的是以下内容。我已经定义了一个接口如下:

type IMatrix =

    abstract member GetSlice : ?start1:int * ?end1:int * ?start2:int * ?end2:int -> IMatrix
    abstract member GetSlice : idx1:int * ?end1:int * ?start2:int * ?end2:int -> IMatrix
    abstract member GetSlice : ?start1:int * ?end1:int * idx2:int -> IMatrix

这是基于我从说明书第6.4.7节中理解的说明。我的想法是,当我有一个名为IMatrix的{​​{1}}时,我应该可以写

matrix

并获取matrix.[1 .. 2, 3 .. 4] 类型的子矩阵。这个想法基本上是IMatrix转换为1 .. 2Some 1, Some 2被编译器转换为3 .. 4,这四种选项类型被赋予四参数{ {1}}方法。

但是,当我在实践中尝试这个时,编译器会报告没有重载与方法'GetSlice'匹配的错误,特别是提到类型'int'与类型'int选项'不兼容。因此在我看来,编译器正确地推断切片概念应该转换为GetSlice调用,但不知何故,参数混淆了。

顺便说一下,如果我在实现一维切片时尝试这个问题,我会遇到同样的问题。一个IVector接口,或者在类而不是接口上尝试这个时。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:5)

我认为编译器只需要将参数显式为int option类型,而不是int类型的可选参数。以下类型检查:

type IMatrix =
  abstract member GetSlice : 
    start1:int option * end1:int option * 
    start2:int option * end2:int option -> IMatrix
  abstract member GetSlice : 
    idx1:int * 
    start2:int option * end2:int option -> IMatrix
  abstract member GetSlice : 
    start1:int option * end1:int option * 
    idx2:int -> IMatrix

let m : IMatrix = failwith "!"
m.[1 .. 2, 3 .. 4]
m.[1, 3 .. 4]
m.[1 .. 2, 3]