기본 자료구조
Quick overview: Basic Structures
리스트
리스트는 변하지 않고, 동적 크기를 가지며, 같은 타입만 담고, 순서가 있는 항목의 묶음입니다. 리스트의 맨 앞에서 항목을 지우거나 추가하는 것은 빠르지만, 임의의 위치에 접근하는 것은 느립니다.
Reason의 리스트는 아주 간단한 단일 연결 리스트 구현입니다.
let listA = [1, 2, 3];
Add to the front using the spread operator ...
:
let listB = [0, ...listA];
let listC = [-1, 0, ...listA];
@
연산자로 리스트를 연결합니다:
let listD = listA @ listB @ [7, 8];
끝에 추가하기
리스트는 단일 연결 리스트 구현이기 때문에 끝에 항목을 추가하는 것이 느립니다. 아래와 같이, 기대했던 문법은 동작하지도, 컴파일되지도 않습니다.
/* 문법 오류 */
let listB = [...listA, 100];
If you need to add to the end and do not care about the operation being slow, then use the concatenate operator:
let listB = listA @ [100];
A common workaround that remains performant is adding to the front of the list, then reversing the list at the end with List.rev
.
Common Functions
- List Functions:
module List
Map
Map over a list to change items according to some function:
let doubled = List.map(i => i * 2, list);
Fold / Reduce
Fold over a list to reduce it to one value (which may be another collection):
let max = List.fold_left(
(result, item) => item > result ? item : result,
initialValue,
list,
);
Reverse
let reversed = List.rev(list);
Length
- Important: This is an O(n) operation, be careful when using this function. It is not constant time.
let n = List.length(list);
Is Empty
let isEmpty = list == [];
Pattern Matching
Pattern matching works with lists:
switch (list) {
| [first, second, ...rest] => "at least two"
| [first, ...rest] => "at least one"
| [] => "empty"
}
Array
Arrays are mutable, fixed sized, homogeneous, and ordered collections of items. Random access on an array is fast, but changing the size of an array requires recreating the entire structure.
let arrayA = [| 1, 2, 3 |];
Access elements using square brackets:
let first = arrayA[0];
let second = arrayA[1];
Update elements using assignment:
arrayA[2] = 23;
Common Functions
- Array Functions:
module Array
Map
Map over an array to change items according to some function:
let doubled = Array.map(i => i * 2, array);
Fold / Reduce
Fold over an array to reduce it to one value (which may be another collection):
let max = Array.fold_left(
(result, item) => item > result ? item : result,
initialValue,
array,
);
Concatenate
let combined = Array.append(arrayA, arrayB);
let combined = Array.concat([arrayA, arrayB, arrayC]);
Length
- Unlike lists this is a constant time operation. It is safe to use anywhere.
let n = Array.length(array);
Dynamic Creation
let zeroes = Array.make(length, 0);
let squares = Array.init(length, i => i * i);
Conversion to List
let list = Array.to_list(array);
let array = Array.of_list(list);
Pattern Matching
Pattern matching works with arrays, but there is no ...rest
syntax like lists have:
switch (array) {
| [||] => "empty"
| [| first |] => "exactly one"
| [| first, second |] => "exactly two"
| _ => "at least three"
};
튜플
Tuples are immutable, constant sized, and heterogeneous collections of items. They provide a way to group values together quickly.
let pair = (1, "hello");
let triple = ("seven", 8, '9');
Access specific items in a tuple using destructuring:
let (_, second) = pair;
let (first, _, third) = triple;
Or pattern matching over a tuple:
switch (pair) {
| ("hello", name) => print_endline("Hello " ++ name);
| ("bye", name) => print_endline("Goodbye " ++ name);
| (command, _) => print_endline("Unknown command: " ++ command);
};
- Note: If a tuple will have many items or be passed around often, then records should be preferred.
레코드
Records are another basic structure that has named fields and heterogeneous values. There is a dedicated article on records: Records.