4

我有一个数组 P 的数组,它表示一个矩阵,作为一个行向量数组(这种表示对我的目的来说更方便),我想提取该数组的列向量 j。我的第一关是:

let column (M: float[][]) (j: int) =
   Array.map(fun v -> v.[j]) M

这无法编译,告诉我 v.[j] 在不确定类型的对象上使用 operator expr.[idx]。这让我感到困惑,因为将鼠标悬停在 v 上会将 v 识别为 float[],我认为它是一个行向量。

此外,以下代码有效:

let column (M: float[][]) (j: int) =
   Array.map(fun v -> v) M
   |> Array.map (fun v -> v.[j])

我无法理解第二个示例与第一个示例有何不同。第二个示例中的第一个映射看起来是多余的:我将一个数组映射到自身,但这似乎解决了类型确定问题。

任何帮助理解我做错了什么或没有看到将不胜感激!

4

2 回答 2

6

问题是 F# 类型推断严格从左到右,以便编译器看到

let column (M: float[][]) (j: int) =
   Array.map(fun v -> v.[j]) 

在这一点上,它完全不知道,v所以它会抛出一个错误。这就是正向管道运算符|>如此普遍的原因 - 将您的代码重写为

let column (M: float[][]) (j: int) =
   M |> Array.map(fun v -> v.[j]) 

没问题。这也是您的第二个示例有效的原因

于 2012-05-24T04:39:19.653 回答
3

由于类型检查器从左到右工作,因此 type ofv未指定,尽管 type ofM稍后可用。所以:

let column (M: float[][]) (j: int) =
   M |> Array.map (fun v -> v.[j])

或者

let column M (j: int) =
   Array.map (fun (v: float []) -> v.[j]) M

作品。

在第二个示例fun v -> v中,任何类型都可以。所以数组元素的类型没有问题。第二部分|>按预期工作,并说明了为什么我们应该使用管道运算符。

于 2012-05-24T04:50:09.210 回答