OCaml Functional language

Version 5.5 · source

Start here

let x = 1
Bind a value
let f x = x + 1
Define a function
match v with | ...
Pattern match
type t = A | B of int
Declare a variant
dune build
Build the project
dune exec ./bin/main.exe
Run the program
dune test
Run tests
utop
Interactive toplevel

Concepts

  1. opam switch + packages
  2. dune dune-project, dune files
  3. ocamlfind / ocamlopt native or bytecode
  4. Executable _build/default

Values & functions

let x = 42
Bind a name to a value
let x = 1 in x + 1
Local binding in an expression
let add a b = a + b
Define a function
let sq = fun x -> x * x
Anonymous function
let rec fact n = if n <= 1 then 1 else n * fact (n - 1)
Recursive function
let add5 = add 5
Partial application
f @@ g x
Apply f to the result of g x
x |> f |> g
Pipe a value through functions
let f ~name ?(n = 1) () = ...
Labelled and optional arguments
let (a, b) = pair
Destructure a tuple
let f = function | 0 -> "zero" | _ -> "other"
Function over one matched argument
let x = ref 0 in x := !x + 1
Mutable reference
if c then a else b
Conditional expression
for i = 0 to n - 1 do ... done
For loop
while c do ... done
While loop
print_endline "hi"
Print a line
Printf.printf "%d %s\n" n s
Formatted output
Printf.sprintf "%.2f" x
Format to a string

Types & pattern matching

type t = Red | Green | Blue of int
Variant type
type p = { name : string; age : int }
Record type
{ p with age = 31 }
Copy a record with a change
type 'a tree = Leaf | Node of 'a tree * 'a * 'a tree
Recursive polymorphic type
match v with | A -> 1 | B n -> n
Match a variant
| x :: rest -> ... | [] -> ...
Match list head and tail
| Some x -> x | None -> d
Match an option
| n when n > 0 -> ...
Guard in a pattern
| (1 | 2) as n -> ...
Or-pattern with alias
let p = { name = "Ann"; age = 30 }
Build a record
p.age
Read a record field
type t = { mutable n : int }
Mutable record field
type id = int
Type alias
`Tag 3
Polymorphic variant value
exception Oops of string
Declare an exception
try f () with Not_found -> d
Catch an exception
raise (Failure "msg")
Raise an exception
assert (x > 0)
Assertion

Option & result

Some x / None
Optional value
Option.map f o
Map over a present value
Option.value o ~default:d
Unwrap with a default
Option.bind o f
Chain optional steps
Option.is_some o
Test for presence
Ok v / Error e
Result values
Result.map f r
Map over Ok
Result.bind r f
Chain fallible steps
let* x = r in ...
Result/option binding operator
Result.get_ok r
Unwrap Ok or raise

Lists & arrays

[1; 2; 3]
List literal (semicolons)
x :: xs
Prepend to a list
a @ b
Concatenate lists
List.map f l
Transform each element
List.filter p l
Keep matching elements
List.fold_left f acc l
Reduce from the left
List.iter f l
Run for side effects
List.length l
Number of elements
List.rev l
Reverse a list
List.mem x l
Membership test
List.find_opt p l
First match as option
List.assoc_opt k l
Look up in association list
List.sort compare l
Sort a list
List.init n f
Build from an index function
List.exists p l / List.for_all p l
Any / all match
List.nth l i
Element at index (raises)
[| 1; 2; 3 |]
Array literal
a.(i) / a.(i) <- v
Read / write array element
Array.make n 0
Array of n copies
Array.length a
Array size
Array.iter f a / Array.map f a
Iterate / transform array

Strings & I/O

"ab" ^ "cd"
Concatenate strings
String.length s
String length
String.sub s pos len
Substring
String.split_on_char ',' s
Split on a character
String.concat ", " l
Join a list of strings
String.trim s
Strip surrounding whitespace
String.uppercase_ascii s
Uppercase ASCII
string_of_int n / int_of_string s
Convert int and string
float_of_int n
Int to float
String.equal a b
String equality
Buffer.add_string b s
Append to a buffer
read_line ()
Read a line from stdin
In_channel.with_open_text f In_channel.input_all
Read a whole file
Out_channel.with_open_text f (fun oc -> ...)
Write a file
Sys.argv
Command-line arguments

Modules

module M = struct ... end
Define a module
module type S = sig ... end
Declare a signature
module M : S = struct ... end
Constrain a module to a signature
open M
Bring names into scope
let open M in ...
Open locally
M.(expr)
Local open shorthand
module F (X : S) = struct ... end
Functor definition
module IntMap = Map.Make (Int)
Instantiate Map
module StrSet = Set.Make (String)
Instantiate Set
Hashtbl.create 16
Mutable hash table
Hashtbl.replace h k v
Set a key
Hashtbl.find_opt h k
Look up a key
include M
Copy a module's items in
file.ml / file.mli
Implementation and interface

Dune

dune init project <name>
Create a project
dune build
Build everything
dune build -w
Rebuild on file changes
dune exec <name>
Build and run an executable
dune exec ./bin/main.exe -- <args>
Run with arguments
dune test
Run tests
dune runtest --auto-promote
Accept expected-test output
dune clean
Delete _build
dune fmt
Format with ocamlformat
dune utop <dir>
Toplevel with the library loaded
dune build @doc
Generate odoc documentation
dune build @check
Typecheck without linking
dune install
Install built packages
dune build --release
Build without dev warnings-as-errors

opam & toolchain

opam init
One-time setup
opam install <pkg>
Install a package
opam search <text>
Search packages
opam update && opam upgrade
Refresh and upgrade
opam list
Show installed packages
opam switch create <name> <version>
New switch with a compiler
opam switch list
List switches
opam switch <name>
Select a switch
eval $(opam env)
Load the switch into the shell
opam install --deps-only .
Install project dependencies
opam switch create . --deps-only
Local switch for a project
opam pin add <pkg> <path-or-url>
Use a local or git version
opam exec -- <cmd>
Run a command in the switch
opam install ocaml-lsp-server ocamlformat utop
Editor and dev tools
ocaml -version
Show compiler version

Toplevel & compiler

utop
Interactive toplevel with history
ocaml
Plain toplevel
ocaml <file.ml>
Run a script
#use "file.ml";;
Load a file in the toplevel
#require "<lib>";;
Load a findlib library
#show <name>;;
Show a type or module signature
ocamlfind ocamlopt -package <lib> -linkpkg f.ml
Compile natively with a package
ocamlfind ocamlopt f.ml -o f
Compile natively
ocamlc -c f.mli
Compile an interface
ocamlfind list
List installed findlib packages

Recipes

New project to first run
opam switch create . --deps-onlydune init project hellocd hellodune exec hello
Minimal dune files
# dune-project(lang dune 3.0)# bin/dune(executable  (name main)  (libraries str))
Expect test
let%expect_test _ =  print_endline "hi";  [%expect {| hi |}]# dune: (inline_tests) (preprocess (pps ppx_expect))
Sum a list with a fold
let sum l = List.fold_left ( + ) 0 llet () = [1; 2; 3] |> sum |> Printf.printf "%d\n"