【问题标题】:Using Array.map on an array of arrays在数组数组上使用 Array.map
【发布时间】:2012-05-30 15:56:30
【问题描述】:

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

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

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

【问题讨论】:

    标签: arrays f#


    【解决方案1】:

    由于类型检查器从左到右工作,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 在任何类型上都可以。所以数组元素的类型没有问题。 |> 的第二部分按预期工作,并说明了为什么我们应该使用管道运算符。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 感谢您的解释。关于intellisense正确识别v的类型这一事实,我是否应该推断它比编译器更了解它?
      • @Mathias - 这似乎是正确的,但我不知道智能感知是如何工作的
      猜你喜欢
      • 2019-09-02
      • 2019-02-01
      • 2017-05-30
      • 2017-05-16
      • 1970-01-01
      • 1970-01-01
      • 2020-08-19
      • 2018-06-18
      • 2016-10-29
      相关资源
      最近更新 更多