在数组数组上使用Array.map

时间:2012-05-24 04:30:03

标签: arrays f#

我有一个数组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])

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

任何有助于了解我做错了什么或不看的内容都会非常感激!

2 个答案:

答案 0 :(得分:5)

问题是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]) 

很好。这也是你的第二个例子工作的原因

答案 1 :(得分:3)

由于类型检查器从左向右工作,因此v的类型未指定,尽管M的类型稍后可用。因此:

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都可以。所以数组元素的类型没有问题。 |>的第二部分按预期工作,并再说明为什么我们应该使用管道运算符。