gpt4 book ai didi

f# - 数组模式匹配

转载 作者:行者123 更新时间:2023-12-05 00:40:51 25 4
gpt4 key购买 nike

是否可以像 F# 中的列表一样使用模式匹配来遍历数组?我尝试过这样的事情:

type Alphabet = A | B

let rec calc (l: Alphabet []) = match l with
|l when l.[0] = A -> 5+(calc l.[1..])
|l when l.[0] = B -> 10+(calc l.[1..])
|l when l = [||] -> 0
calc [|A;A;B|]

问题似乎是循环继续并导致堆栈溢出。有可能吗?

最佳答案

我认为您正在尝试这样做:

let toInteger = function
| A -> 5
| B -> 10

[|A; A; B|] |> Array.sumBy toInteger

在模式匹配中,可以使用数组模式:例如,[|a;乙; c|] 匹配三元素数组。但是数组没有 :: 运算符,因此像使用列表一样使用数组很麻烦。这是因为如果不复制它,您无法将数组的尾部作为新数组。

问题的代码有很多问题:

  • 由于超出数组范围而崩溃。这是因为您没有验证 .[1..] 切片是否存在。
  • 它不是尾递归的。这可能是您在长列表中看到堆栈溢出的原因。
  • 两个功能混合在一个函数中,使阅读变得复杂:转换为整数和求和。
  • 编译器无法验证模式匹配是否涵盖所有情况,因此会发出警告。
  • 如前所述,复制数组的成本很高。该算法的数组长度为 O(n^2),因此对于长数组来说非常昂贵。与 Array.sumBy 或索引到数组的尾递归函数不同,它们根本不需要复制数组。

这里问题的核心是数组和单链不可变列表之间的区别。数组适合通过增加索引来迭代它们( Array.sumBy 在内部执行),而列表允许将其尾部视为独立列表而无需任何复制( List.sumBy 确实内部)。通常最好按照预期的方式使用每个数据结构。

关于f# - 数组模式匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43492505/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com