F# 为受约束的泛型参数创建实例方法
F# create instance method for a constrained generic parameter
是否可以有一个 class 的实例方法,它只在泛型类型被限制为特定类型时才有效?
例如,我想定义一个 Add
方法,该方法仅在包含的类型为 float
时有效。这是我得到的最接近的,但我不确定如何在成员 _.Add
签名中将 'Value
类型限制为 float
。现在我在最后一行的旁边收到一条错误消息,说 'Value
的类型无法在编译时解析。我可以限制此方法仅在 'Value
的类型为 float
时应用吗?
type ImArr<[<Measure>] 'Index, 'Value>(values: array<'Value>) =
// We want to make sure we have our own copy to protect against mutation
let values = values |> Array.copy
member internal _.Values : array<'Value> = values
member this.Item
with get(index: int<'Index>) =
values.[int index]
type Arr<[<Measure>] 'Index, 'Value>(values: array<'Value>) =
// We want to make sure we have our own copy to protect against mutation
let values = values |> Array.copy
member this.Item
with get(index: int<'Index>) =
values.[int index]
and set(index: int<'Index>) (value: 'Value) =
values.[int index] <- value
member internal _.Values : array<'Value> = values
// This is the method I would like to constrain to only be used when the
// type of 'Value is float
member _.Add (b: ImArr<'Index, float>) =
if values.Length <> b.Values.Length then
invalidArg (nameof b) "Cannot add arrays of different lengths"
// TODO: Turn this into something using SIMD intrinsics
let mutable i = 0
while i < values.Length && i < b.Values.Length do
values.[i] <- values.[i] + b.Values.[i] // <-- Error here
i <- i + 1
正如@brianberns 在评论中提到的,不是直接提到的。但是,可以为 class 的特殊版本定义 C#-style extension methods。需要注意的是,作为扩展方法,它无法访问私有成员。
[<Extension>]
type ArrExtensions =
[<Extension>]
static member Add (this: ImArr<'Index, float>, b: ImArr<'Index, float>) =
if this.Values.Length <> b.Values.Length then
invalidArg (nameof b) "Cannot add arrays of different lengths"
// TODO: Turn this into something using SIMD intrinsics
let mutable i = 0
while i < this.Values.Length && i < b.Values.Length do
this.Values.[i] <- this.Values.[i] + b.Values.[i] // <-- Error here
i <- i + 1
// When the namespace containing the above type is opened,
// the following can be called:
floatArr1.Add(floatArr2)
是否可以有一个 class 的实例方法,它只在泛型类型被限制为特定类型时才有效?
例如,我想定义一个 Add
方法,该方法仅在包含的类型为 float
时有效。这是我得到的最接近的,但我不确定如何在成员 _.Add
签名中将 'Value
类型限制为 float
。现在我在最后一行的旁边收到一条错误消息,说 'Value
的类型无法在编译时解析。我可以限制此方法仅在 'Value
的类型为 float
时应用吗?
type ImArr<[<Measure>] 'Index, 'Value>(values: array<'Value>) =
// We want to make sure we have our own copy to protect against mutation
let values = values |> Array.copy
member internal _.Values : array<'Value> = values
member this.Item
with get(index: int<'Index>) =
values.[int index]
type Arr<[<Measure>] 'Index, 'Value>(values: array<'Value>) =
// We want to make sure we have our own copy to protect against mutation
let values = values |> Array.copy
member this.Item
with get(index: int<'Index>) =
values.[int index]
and set(index: int<'Index>) (value: 'Value) =
values.[int index] <- value
member internal _.Values : array<'Value> = values
// This is the method I would like to constrain to only be used when the
// type of 'Value is float
member _.Add (b: ImArr<'Index, float>) =
if values.Length <> b.Values.Length then
invalidArg (nameof b) "Cannot add arrays of different lengths"
// TODO: Turn this into something using SIMD intrinsics
let mutable i = 0
while i < values.Length && i < b.Values.Length do
values.[i] <- values.[i] + b.Values.[i] // <-- Error here
i <- i + 1
正如@brianberns 在评论中提到的,不是直接提到的。但是,可以为 class 的特殊版本定义 C#-style extension methods。需要注意的是,作为扩展方法,它无法访问私有成员。
[<Extension>]
type ArrExtensions =
[<Extension>]
static member Add (this: ImArr<'Index, float>, b: ImArr<'Index, float>) =
if this.Values.Length <> b.Values.Length then
invalidArg (nameof b) "Cannot add arrays of different lengths"
// TODO: Turn this into something using SIMD intrinsics
let mutable i = 0
while i < this.Values.Length && i < b.Values.Length do
this.Values.[i] <- this.Values.[i] + b.Values.[i] // <-- Error here
i <- i + 1
// When the namespace containing the above type is opened,
// the following can be called:
floatArr1.Add(floatArr2)