编译时未解析类型的 F# 类型错误
F# type error with unresolved type at compile time
我正在尝试一个实验,我正在包装一些数组以确保索引上的单位。我在此处的最后一行代码中遇到编译器错误。这是说类型参数 'Value' 不能使用,因为类型参数无法在编译时解析。我无法弄清楚为什么这会导致错误。我还尝试更改方法签名以限制 'Value
在两个数组中相同。
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 = 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 internal _.Values = values
member inline _.Add (x: ImArr<'Index,_>) =
if values.Length <> x.Values.Length then
invalidArg (nameof x) "Cannot add arrays of different lengths"
for idx = 0 to values.Length - 1 do
values.[idx] <- values.[idx] + x.Values.[idx] // Error on this line
我试过的另一个方法签名也引发了错误。
member inline _.Add (x: ImArr<'Index,_>) =
错误消息图片:
我也尝试将工作提取到一个单独的函数中并得到了相同的结果。
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= 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 = values
module Helpers =
let inPlaceAdd<[<Measure>] 'Index, 'Value> (a: Arr<'Index, 'Value>) (b: ImArr<'Index, 'Value>) =
let mutable i = 0;
while i < a.Values.Length && i < b.Values.Length do
a.Values.[i] <- a.Values.[i] + b.Values.[i] // ERROR
i <- i + 1
并且编译错误
a.Values.[i] <- a.Values.[i] + b.Values.[i]
----------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^
stdin(31,29): error FS0001: The declared type parameter 'Value' cannot be used here since the type parameter cannot be resolved at compile time
我认为这里的主要问题是编译器不知道如何将两个泛型 'Value
相加。由于编译器无法推断如何执行此操作,您可能需要通过 statically resolved type parameters (SRTP) 给它一个提示,不幸的是,这在 F# 中非常不稳定。通过反复试验,我想出了一个版本的你的辅助函数,它编译时有一个警告但似乎可以工作:
let inline internal inPlaceAdd<[<Measure>] 'Index, ^Value when ^Value : (static member (+) : ^Value * ^Value -> ^Value)> (a: Arr<'Index, 'Value>) (b: ImArr<'Index, 'Value>) =
let mutable i = 0;
while i < a.Values.Length && i < b.Values.Length do
let x = (^Value : (static member (+) : ^Value * ^Value -> ^Value)(a.Values.[i], b.Values.[i]))
a.Values.[i] <- x
i <- i + 1
请注意极其复杂的加法调用,它会导致编译器警告 FS0077: Member constraints with the name 'op_Addition' are given special status by the F# compiler...
。当然,您应该能够直接添加值,如下所示:
let x = a.Values.[i] + b.Values.[i]
但由于某种原因,它无法编译:A type parameter is missing a constraint 'when ( ^Value or ^?11121) : (static member ( + ) : ^Value * ^?11121 -> ^?11122)'
这对我来说似乎是一个编译器错误,但谁知道呢。
用法:
let a = Arr([|1; 2; 3|])
let b = ImArr([|2; 3; 4|])
Helpers.inPlaceAdd a b
printfn "%A" a.Values // [|3; 5; 7|]
这是 F# 编译器的一个已知问题:最好让 F# 编译器推断约束而不是手动编写约束。
这是一个允许 F# 编译器推断它的解决方案:
module Helpers =
let inline inPlaceAdd<[<Measure>] 'Index, .. > (a: Arr<'Index, 'Value>) (b: ImArr<'Index, 'Value>) : unit =
let mutable i = 0;
while i < a.Values.Length && i < b.Values.Length do
a.Values.[i] <- a.Values.[i] + b.Values.[i] // ERROR
i <- i + 1
写起来更容易,而且不会产生任何警告。
我正在尝试一个实验,我正在包装一些数组以确保索引上的单位。我在此处的最后一行代码中遇到编译器错误。这是说类型参数 'Value' 不能使用,因为类型参数无法在编译时解析。我无法弄清楚为什么这会导致错误。我还尝试更改方法签名以限制 'Value
在两个数组中相同。
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 = 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 internal _.Values = values
member inline _.Add (x: ImArr<'Index,_>) =
if values.Length <> x.Values.Length then
invalidArg (nameof x) "Cannot add arrays of different lengths"
for idx = 0 to values.Length - 1 do
values.[idx] <- values.[idx] + x.Values.[idx] // Error on this line
我试过的另一个方法签名也引发了错误。
member inline _.Add (x: ImArr<'Index,_>) =
错误消息图片:
我也尝试将工作提取到一个单独的函数中并得到了相同的结果。
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= 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 = values
module Helpers =
let inPlaceAdd<[<Measure>] 'Index, 'Value> (a: Arr<'Index, 'Value>) (b: ImArr<'Index, 'Value>) =
let mutable i = 0;
while i < a.Values.Length && i < b.Values.Length do
a.Values.[i] <- a.Values.[i] + b.Values.[i] // ERROR
i <- i + 1
并且编译错误
a.Values.[i] <- a.Values.[i] + b.Values.[i]
----------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^
stdin(31,29): error FS0001: The declared type parameter 'Value' cannot be used here since the type parameter cannot be resolved at compile time
我认为这里的主要问题是编译器不知道如何将两个泛型 'Value
相加。由于编译器无法推断如何执行此操作,您可能需要通过 statically resolved type parameters (SRTP) 给它一个提示,不幸的是,这在 F# 中非常不稳定。通过反复试验,我想出了一个版本的你的辅助函数,它编译时有一个警告但似乎可以工作:
let inline internal inPlaceAdd<[<Measure>] 'Index, ^Value when ^Value : (static member (+) : ^Value * ^Value -> ^Value)> (a: Arr<'Index, 'Value>) (b: ImArr<'Index, 'Value>) =
let mutable i = 0;
while i < a.Values.Length && i < b.Values.Length do
let x = (^Value : (static member (+) : ^Value * ^Value -> ^Value)(a.Values.[i], b.Values.[i]))
a.Values.[i] <- x
i <- i + 1
请注意极其复杂的加法调用,它会导致编译器警告 FS0077: Member constraints with the name 'op_Addition' are given special status by the F# compiler...
。当然,您应该能够直接添加值,如下所示:
let x = a.Values.[i] + b.Values.[i]
但由于某种原因,它无法编译:A type parameter is missing a constraint 'when ( ^Value or ^?11121) : (static member ( + ) : ^Value * ^?11121 -> ^?11122)'
这对我来说似乎是一个编译器错误,但谁知道呢。
用法:
let a = Arr([|1; 2; 3|])
let b = ImArr([|2; 3; 4|])
Helpers.inPlaceAdd a b
printfn "%A" a.Values // [|3; 5; 7|]
这是 F# 编译器的一个已知问题:最好让 F# 编译器推断约束而不是手动编写约束。
这是一个允许 F# 编译器推断它的解决方案:
module Helpers =
let inline inPlaceAdd<[<Measure>] 'Index, .. > (a: Arr<'Index, 'Value>) (b: ImArr<'Index, 'Value>) : unit =
let mutable i = 0;
while i < a.Values.Length && i < b.Values.Length do
a.Values.[i] <- a.Values.[i] + b.Values.[i] // ERROR
i <- i + 1
写起来更容易,而且不会产生任何警告。