Ale*_*kol 2 arrays f# functional-programming pattern-matching multidimensional-array
我正在为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
Run Code Online (Sandbox Code Playgroud)
考虑这三个中的最后一个.矩阵类有一个私有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),
Run Code Online (Sandbox Code Playgroud)
它只是简单地使用GetSlice了float[,]实现的功能.但是,这不会编译,因为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),
Run Code Online (Sandbox Code Playgroud)
这将需要16个模式案例,因此有些不方便.有没有更简单的选择,也许是基于某种方式获得对GetSlice扩展方法的访问float[,]?
您可以使用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])
Run Code Online (Sandbox Code Playgroud)