2

F#でマトリックスクラスのスライス式を実装しています。つまり、3つのGetSliceメソッドを実装する必要があります。私の質問は、コアライブラリの既存の機能を活用することでこれを行う効率的な方法を得ることです。 3つの方法の署名は次のとおりです。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 

これら3つの方法の署名について考えてみましょう。マトリックスクラスにはentriesと呼ばれる専用のfloat[,]フィールドがあり、マトリックスデータを保持します。

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[,]ためのスライス表現に基づいて、マニュアル実装では、16パターンの例を必要とし、これ多少不便であるだろう。この

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), 

のようになります。より簡単なオプションはありますか?おそらく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拡張メソッド(別のプロジェクトで動作していたと思っていますか?)の「Go to definition」にヒットした場合、その背後にある「実際の」静的メソッドを見ることができます。それは次のようになります:静的メソッドをF#でうまく動作することを

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

、あなたは、通常の代わりに、拡張構文を通してそれを呼び出すためにだけ必要があります。

+0

まあ、私は実際にどのモジュールでfloat [、]のGetSlice拡張子を見つけるのかわかりませんし、VS2015でも検出されないので "Go to definition"で見ることができません。 F#でスライス式を使用できるので、それが存在することがわかります。 –

関連する問題