5

F#支持「切片表達式」,例如,對於常規的一維陣列myArray允許表達如myArray.[3 .. 5]。根據例如F#4.0語言規範(第6.4.7節),這是通過適當轉換參數後調用GetSlice方法實現的。這也適用於多維數組。但是,我在定義一個在二維情況下實現它的接口時遇到了一些問題。在F#接口中實現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節中瞭解到的說明。這個想法是,當我再有一個名爲IMatrixmatrix,我應該能夠編寫

matrix.[1 .. 2, 3 .. 4] 

,並得到IMatrix類型的子陣。這個想法本質上是,1 .. 2被編譯器轉換爲Some 1, Some 23 .. 4被轉換爲Some 3, Some 4,並且這四種選項類型被給予四參數GetSlice方法。

但是,當我在實踐中嘗試這樣做時,編譯器報告沒有重載與方法'GetSlice'匹配的錯誤,特別提及'int'類型與'int option'類型不兼容。因此,在我看來,編譯器正確地推斷切片概念應該轉換爲GetSlice調用,但不知何故,這些參數會混淆起來。另外,如果我在實現一維切片時嘗試這樣做,我會遇到同樣的問題。一個IVector接口,或者在一個類而不是一個接口上試用這個接口。

我該如何解決這個問題?

+0

看看規範,似乎'matrix。[1..2,3..4]'被翻譯成'matrix.GetSlice((Some(1),Some(2 )),(Some(3),Some(4))'所以你的實現應該採用'int option'而不是'int'。 – Lee

回答

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]