Willem Hoek

OCaml notes

Mar 07, 2019

Install OCaml

Install on Linux

sudo apt-get update -y && apt-get upgrade -y
sudo apt-get install m4 patch ocaml -y

Install OPAM as per notes https://opam.ocaml.org/doc/Install.html

sudo apt-get install opam

else

wget https://raw.github.com/ocaml/opam/master/shell/opam_installer.sh -O - | sh -s /usr/local/bin

Install rest via opam

opam init
opam update
opam upgrade
opam switch
opam switch list-available
opam switch list-available base
opam switch create 4.10.0

# issue with OCaml on debian -    https://github.com/ocaml/opam/issues/3827
rm -rf ~/.opam
apt install mccs
opam init --solver=mccs
opam switch create 4.10.0 --solver=mccs

This will take a few minutes.

For installed version of OCaml - get required tools/libraries via opam

opam install utop tuareg merlin user-setup 
opam user-setup install

For OCaml on Windows (cygwin):

opam install depext depext-cygwinports

Better to use following to install packages – as it take care of dependencies. E.g. to install sqlite3 package

opam depext -i sqlite3

Reference documents

Cheat sheet - https://ocaml.org/docs/cheat_sheets.html

User Manual - https://caml.inria.fr/pub/docs/manual-ocaml/

Core Library - https://caml.inria.fr/pub/docs/manual-ocaml/libref/index.html

Pattern match

https://ocaml.org/learn/tutorials/data_types_and_matching.html#Pattern-matching-on-datatypes

(*    pair : int * int -> int -> int = <fun>    *)

let pair k p =
  match k, p with
  | (1, _), _ -> 1
  | _, 2 -> 222
  | _, _ -> 0

The next are are the same.

(*    first : int list -> string = <fun>    *)

let first l =
  match l with
  | a :: b :: _ when a = b -> "double"
  | 1 :: _ -> "one"
  | _ -> "other"

let first = function
  | a :: b :: _ when a = b -> "double"
  | 1 :: _ -> "one"
  | _ -> "other"

Lists

https://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html

let a = List.init 5 (fun x -> x * 2);;
(* int list = [0; 2; 4; 6; 8]   *)

List.map (fun x -> x * 2) a;;
(* int list = [0; 4; 8; 12; 16]  *)

List.iter (fun x -> print_int x) a;;
(* 02468 *)

List.iteri (fun i x -> print_int (x + i)) a;;
(* 036912   *)

Avoid using for loop when List.iter can be used.

let my_list = [1;2;3;4]

let () = 
  for n = 0 to (List.length my_list - 1) do
    print_int (List.nth my_list n)
  done
(* 1234 *)

let () = List.iter print_int my_list
(* 1234 *)

Arrays

https://caml.inria.fr/pub/docs/manual-ocaml/libref/Array.html

Array.make 5 1;;
(* int array = [|1; 1; 1; 1; 1|]    *)

Array.init 5 (fun x -> x + 1);;
(* int array = [|1; 2; 3; 4; 5|]     *)

let a = Array.make_matrix 2 3 1;;     (* where x=2  y=3 *)
(* val a : int array array = [|[|1; 1; 1|]; [|1; 1; 1|]|]   *)

a.(0).(0) <- 100;;
a;;
(* int array array = [|[|100; 1; 1|]; [|1; 1; 1|]|]   *)
let create_grid n = Array.init n (fun y ->
                        Array.init n (fun x ->
                            y * n + x
                          )
                      )

let print_grid g =
  let n = Array.length g in
  for y = n-1 downto 0  do
    for x = 0 to n-1 do
      Printf.printf "%3i%!" g.(x).(y)
    done;
    Printf.printf "\n%!"
  done

let a = create_grid 3
(* val a : int array array = [|[|0; 1; 2|]; [|3; 4; 5|]; [|6; 7; 8|]|] *)

let () = print_grid a
(*
  2  5  8
  1  4  7
  0  3  6
 *)

Named and Default arguments

(* ~foo -- named argument *)

let div ~top y  = top  / y;;

(* or *)
let div ~top:x y  = x / y;;

div 8 2;;
(* 4 *)

div 2 ~top:8;;
(* 4 *)

(* ?bar -- Named argument with a default. Cannot be used with last argument. *)
let f1  ?a:(aa=4) ~b c = aa + b  + c;;
(* val f1 : ?a:int -> b:int -> int -> int  *)

let f2  ?(a=4) ~b c = a + b  + c;;
(* val f2 : ?a:int -> b:int -> int -> int  *)

f1 1 2;;
(* 7 *)

f1 1 2 3;;
(* Error: This argument cannot be applied without label *)

f1 ~a:3 ~b:1 2;;
(* 6 *)

Related Posts

Jane Street puzzle Feb 2021 SOLVED! OCaml to the rescue

Solving the Jane Street puzzle of Dec 2020 - Backtracking with OCaml

Automate your Jira reporting with Python and Excel

Solving the Jane Street Puzzle of June 2020; Circle Time

Solving the Jane Street Puzzle of May 2020; Expelled with OCaml

Never forget a birthday again with GitHub Actions and Python