更新时间:2023-02-05 14:32:40
欢迎使用推理!
在Reason/OCaml中,列表是不可变的.在后台,它们是简单的单链接列表.每次修改"它们时,您都要创建新的.这是一个示例:
let a = [1, 2, 3];
let b = [0, ...a];
这类似于JavaScript的数组"spread",不同的是这里要使用现有的a
,在前面链接一个新节点0
,并将其命名为b. a
仍指向[1, 2, 3]
(因此为不变"). b
现在是[0, 1, 2, 3]
.这是有效的,因为[1, 2, 3]
部分是共享的.
这样做的好处是,您不必担心传递列表的麻烦,而无需意外地使用晦涩的功能对其进行修改. List的不变性使您可以纯粹通过查看您现在盯着的值来推理代码(因为它永远不会改变!).
list的缺点是在末尾添加内容效率很低:
let c = a @ [4]
该操作基本上是获取一项[4]
的列表,并依次将[1, 2, 3]
的每一项附加到该列表.因此,在性能方面呈线性关系.但是从列表实现的简单性来看,从历史上看,这是值得权衡的.
所以3.如果您要设置列表项,那就错了.
let newList = List.map (fun blabla => ...) raw
Array.of_list
和Array.to_list
.有关数组的更多信息:OCaml数组是可变的,并且其大小不可更改.将其视为内存块.您可以通过Array.make newSize
分配一个新数组,然后通过Array.set
进行填充.如果您要大量调整数组的大小,那么这是没有意义的,因此请选择正确的数据结构.
对于JS编译,BuckleScript将ocaml数组编译为JS数组.因此,它是可变的和可调整大小的.您将在 Js.Array
下找到熟悉的JS数组操作>
作为一般启发式方法,如果您想更改长度,请尝试filter
.如果要更改长度和包含的项目,请尝试fold_left
.否则,map
.
最近,我们开始实现一些不变的,可调整大小的,可选的可变数组.敬请期待!
I am new at reason / ocaml / functional programming.
I know about List.append
and [] @ []
but these functions will create new list but how to populate existing list / array?
let coords: array point = [];
Reason code:
type point = {x: int, y: int};
let coords: list point = [];
let append raw =>
Array.iter
(
fun data => {
let p = {x: data.x, y: data.y};
/* how to append p to coords */
()
}
)
raw;
JS analogue:
const coords = [];
const append = raw => raw.forEach({x, y} => {
coords.push({
x: process(x),
y: process(y)
});
});
Welcome to Reason!
In Reason/OCaml, lists are immutable. Under the hood they're simple singly-linked list. You create new ones each time you "modify" them. Here's an example:
let a = [1, 2, 3];
let b = [0, ...a];
This is akin to JavaScript's array "spread", except here you're taking the existing a
, linking a new node 0
at the front, and calling it b. a
still points to [1, 2, 3]
(thus "immutable"). b
is now [0, 1, 2, 3]
. This is efficient since the [1, 2, 3]
part is shared.
The advantage of this is that you don't have to worry about passing your list around and accidentally have an obscure function modify it. List's immutability allows you to reason about your code purely by looking at the value you're staring right now (since it'll never change!).
The drawback of list is that it's inefficient to add something at the end:
let c = a @ [4]
That operation's basically taking a list of one item, [4]
, and successively attaching each item of [1, 2, 3]
to it. So linear in terms of perf. But judging by the simplicity of the list implementation, it was historically deemed worth the tradeoff.
So 3. it's the wrong flow if you're trying to set a list item.
let newList = List.map (fun blabla => ...) raw
Array.of_list
and Array.to_list
if you're ever stuck.More on array: OCaml array is mutable, and its size is unchangeable. Think of it as a block of memory. You'd allocate a new array through Array.make newSize
, then populate it through Array.set
. This wouldn't make sense if you're resizing the array a lot, so choose the right data structure.
For JS compilation, BuckleScript compiles an ocaml array to a JS array. It's thus mutable and resizable. You'll find your familiar JS array operations under Js.Array
As a general heuristic, if you'd like to change the length: try filter
. If you'd like to change the length and the contained items, try fold_left
. Otherwise, map
.
More recently, we've started implementing some immutable, resizable, optionally mutable array. Stay tuned!