use*_*037 13 ocaml functional-programming
对于列表,您可以进行模式匹配并迭代直到第n个元素,但对于元组,您将如何获取第n个元素?
Mic*_*ald 11
您可以抓取Ñ由个元素拆包的吨与值解构-uple,或者通过一个let构建体,match构建体或函数定义:
let ivuple = (5, 2, 1, 1)
let squared_sum_let =
let (a,b,c,d) = ivuple in
a*a + b*b + c*c + d*d
let squared_sum_match =
match ivuple with (a,b,c,d) -> a*a + b*b + c*c + d*d
let squared_sum_fun (a,b,c,d) =
a*a + b*b + c*c + d*d
Run Code Online (Sandbox Code Playgroud)
该match-construct在这里有没有凭借在let-construct,它只是为了保持完整性的缘故.
只有少数情况下使用t -uples来表示类型是正确的.很多时候,我们选择一个牛逼 -uple因为我们懒得去定义一个类型,我们应该解释访问的问题ñ一的个场牛逼 -uple或迭代一个领域牛逼 -uple作为严重的信号,是时候切换到合适的类型.
t -uples 有两个自然替代品:记录和数组.
我们可以看到一个记录作为一个牛逼 -uple其项被标记,这样,他们肯定是最自然的更换,以牛逼 -uples如果我们想直接访问它们.
type ivuple = {
a: int;
b: int;
c: int;
d: int;
}
Run Code Online (Sandbox Code Playgroud)
然后,我们通过写入直接访问类型a值的字段.请注意,记录很容易通过修改进行复制,如.没有自然的方法来迭代记录的字段,主要是因为记录不需要是同构的.xivuplex.alet y = { x with d = 0 }
大型²同构值集合由数组充分表示,允许直接访问,迭代和折叠.可能不方便的是,数组的大小不是其类型的一部分,但对于固定大小的数组,通过引入私有类型(甚至是抽象类型)可以很容易地避免这种情况.我在回答 "OCaml编译器检查向量长度"这个问题时描述了这种技术的一个例子.
在t- uples中使用浮点数时,在仅包含浮点数和数组的记录中,这些都是未装箱的.因此,在数值计算中从一种类型更改为另一种类型时,我们不应该注意到任何性能修改.
¹请参阅TeXbook.²大于4开始.
由于OCaml元组的长度是类型的一部分,因此在编译时已知(并且已修复),因此您可以通过元组上的直接模式匹配来获得第n个项目.出于同样的原因,在实践中不能发生提取"任意长度元组"的第n个元素的问题- 这样的"元组"不能在OCaml的类型系统中表达.
您可能仍然不希望每次需要投射元组时都写出模式,并且没有什么能阻止您生成函数get_1_1...... 从-tuple get_i_j中提取i-th元素以j用于任何可能的组合i和j发生在你的代码中,例如
let get_1_1 (a) = a
let get_1_2 (a,_) = a
let get_2_2 (_,a) = a
let get_1_3 (a,_,_) = a
let get_2_3 (_,a,_) = a
...
Run Code Online (Sandbox Code Playgroud)
不一定漂亮,但可能.
注意:以前我声称OCaml元组最多可以有255个长度,你可以简单地一劳永逸地生成所有可能的元组投影.正如@Virgile在评论中指出的那样,这是不正确的 - 元组可能是巨大的.这意味着预先生成所有可能的元组投影函数是不切实际的,因此上面的限制" 发生在您的代码中 ".
| 归档时间: |
|
| 查看次数: |
20924 次 |
| 最近记录: |