2

我在F#中爲矩陣類實現了切片表達式,這意味着我必須實現三個GetSlice方法。我的問題是通過利用核心庫中的現有功能來獲得有效的方法。三種方法的簽名如下:訪問F中的GetSlice方法#

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

考慮這三項的最後一項。矩陣類有一個專用的float[,]字段,稱爲entries,它包含矩陣數據。最自然的實現將是這樣的:

member this.GetSlice (?start1 : int, ?end1 : int, ?start2 : int, ?end2 : int) = 
    let newEntries = entries.GetSlice(?start1 = start1, ?end1 = end1, 
             ?start2 = start2, ?end2 = end2) 
    new Matrix(newEntries), 

簡單的使用了float[,]實施GetSlice功能。但是,這不會編譯,因爲GetSlice擴展方法不可用(至少不是用我打開的名稱空間)。我原以爲這種方法在FSharp.Core中默認是可用的,但這似乎並不是真的。基於對float[,]片表達式手動實現可能看起來像這樣

member this.GetSlice (?start1 : int, ?end1 : int, ?start2 : int, ?end2 : int) = 
    let newEntries = match (start1, end1, start2, end2) with 
     | Some(sta1), Some(end1), Some(sta2), Some(end2) -> entries.[sta1 .. end1, sta2 .. end2] 
     | Some(sta1), Some(end1), Some(sta2), None -> entries.[sta1 .. end1, sta2 .. ] 
     (...) 
    new Matrix(entries), 

這將需要16模式的情況下,因此略感不便。有沒有更容易的選擇,或許基於以某種方式訪問​​GetSlice擴展方法float[,]

回答

6

你可以使用defaultArg分配這些選項的值,只是與他們切片陣列上:

member __.GetSlice (?start1 : int, ?end1 : int, ?start2 : int, ?end2 : int) = 
    let start1, end1, start2, end2 = 
    defaultArg start1 0, 
    defaultArg end1 (Array2D.length1 entries - 1), 
    defaultArg start2 0, 
    defaultArg end2 (Array2D.length2 entries - 1) 

    new Matrix (entries.[start1 .. end1, start2 .. end2]) 
0

擴展方法只是語法糖,讓一個靜態方法看起來就像一個實例方法。

如果在GetSlice擴展方法(我猜你看到它在另一個項目中工作?)上點擊「轉到定義」,您將能夠看到它背後的「真實」靜態方法。這將是這樣的:

public static class SomeMatrixUtilityLibrary.ExtensionMethods 
{ 
    public static float[,] GetSlice(this float[,] array2d, 
            int start1, 
            int end1, 
            int start2, 
            int end2) 
    { 
     //... 
    } 
} 

靜態方法將工作在F#就好了,你只需要調用它正常,而不是通過擴展語法。

+0

嗯,我實際上不知道在哪個模塊中找到float [,]的GetSlice擴展名,而且我無法通過「轉到定義」來看它,因爲它甚至沒有被VS2015檢測到。我只知道它存在,因爲它允許我在F#中使用切片表達式。 –