Slices in OCaml

Lists are an important data type in OCaml, providing a flexible interface for sequences. Unlike Go’s slices, OCaml uses immutable lists by default.

(* We'll use the Format module for printing *)
open Format

let main () =
  (* An empty list is represented by [] *)
  let s = [] in
  printf "empty: %a@." (pp_print_list pp_print_string) s;
  
  (* We can create a list with elements *)
  let s = ["a"; "b"; "c"] in
  printf "init: %a@." (pp_print_list pp_print_string) s;
  
  (* We can get the length of a list *)
  printf "len: %d@." (List.length s);
  
  (* We can access elements by their index *)
  printf "get: %s@." (List.nth s 2);
  
  (* To add elements, we use the cons operator :: *)
  let s = "d" :: s in
  let s = s @ ["e"; "f"] in
  printf "add: %a@." (pp_print_list pp_print_string) s;
  
  (* We can copy a list *)
  let c = List.map (fun x -> x) s in
  printf "copy: %a@." (pp_print_list pp_print_string) c;
  
  (* We can slice a list using List.sub *)
  let l = List.sub s 2 3 in
  printf "slice: %a@." (pp_print_list pp_print_string) l;
  
  (* We can create a new list inline *)
  let t = ["g"; "h"; "i"] in
  printf "declare: %a@." (pp_print_list pp_print_string) t;
  
  (* We can compare lists *)
  let t2 = ["g"; "h"; "i"] in
  if t = t2 then
    printf "t == t2@.";
  
  (* We can create multi-dimensional lists *)
  let twoD = List.init 3 (fun i ->
    List.init (i + 1) (fun j -> i + j)
  ) in
  printf "2d: %a@." (pp_print_list (pp_print_list pp_print_int)) twoD

let () = main ()

To run this program, save it as lists.ml and use the OCaml compiler:

$ ocamlc -o lists lists.ml
$ ./lists
empty: 
init: a b c
len: 3
get: c
add: d a b c e f
copy: d a b c e f
slice: c e f
declare: g h i
t == t2
2d: [0] [1 2] [2 3 4]

Note that OCaml’s lists are immutable, so operations that seem to modify a list actually create a new list. The @ operator is used for list concatenation, and :: is used to add an element to the front of a list.

OCaml’s standard library provides many useful functions for working with lists, such as List.map, List.filter, and List.fold_left. These are powerful tools for list manipulation and are commonly used in functional programming.

In OCaml, multi-dimensional lists are represented as lists of lists. The inner lists can have varying lengths, providing flexibility similar to Go’s slices of slices.

Now that we’ve seen lists in OCaml, we’ll look at another key data structure: maps (which are called association lists or hash tables in OCaml, depending on the implementation).