OJaml / docsProject documentation

Reference

Typed Standard Library

Look up syntax, contracts, layouts, algorithms, and exact behavior.

The standard library is part of the type environment, not an untyped escape hatch. Each builtin has a visible signature and a type factory. When the checker creates the builtins map, the factory constructs the type graph for that builtin. When a builtin is referenced, the checker freshens the graph so each call site receives independent variables.

let main =
  let names = Map.set (Map.empty ()) "ada" 1815 in
  if Map.has names "ada"
  then Map.get names "ada"
  else 0
Typed map success. Map.set fixes names as a (string, int) map; Map.has and Map.get must use string keys, and Map.get returns int.
Array.make⁡:int→′a→′a  arrayArray.length⁡:′a  array→intArray.get⁡:′a  array→int→′aArray.set⁡:′a  array→int→′a→unitArray.append⁡:′a  array→′a  array→′a  arrayArray.reverse⁡:′a  array→′a  arrayArray.map⁡:(′a→′b)→′a  array→′b  arrayArray.filter⁡:(′a→bool)→′a  array→′a  arrayArray.exists⁡:(′a→bool)→′a  array→boolArray.for_all⁡:(′a→bool)→′a  array→bool\begin{aligned}\operatorname{Array.make}&: int \rightarrow 'a \rightarrow 'a\;array\\\operatorname{Array.length}&: 'a\;array \rightarrow int\\\operatorname{Array.get}&: 'a\;array \rightarrow int \rightarrow 'a\\\operatorname{Array.set}&: 'a\;array \rightarrow int \rightarrow 'a \rightarrow unit\\\operatorname{Array.append}&: 'a\;array \rightarrow 'a\;array \rightarrow 'a\;array\\\operatorname{Array.reverse}&: 'a\;array \rightarrow 'a\;array\\\operatorname{Array.map}&: ('a \rightarrow 'b) \rightarrow 'a\;array \rightarrow 'b\;array\\\operatorname{Array.filter}&: ('a \rightarrow bool) \rightarrow 'a\;array \rightarrow 'a\;array\\\operatorname{Array.exists}&: ('a \rightarrow bool) \rightarrow 'a\;array \rightarrow bool\\\operatorname{Array.for\_all}&: ('a \rightarrow bool) \rightarrow 'a\;array \rightarrow bool\end{aligned}
Array API. Array creation, length, reads, writes, append, and reverse preserve a single element type.

Polymorphic collections force the signature table to connect every repeated type variable at the call site. Array.make connects its element argument to the returned array element type. Array.append and List.append require both operands and the result to share one element type. Array.reverse and List.reverse return a collection with the same element type as the input. Array.filter and List.filter require predicates over the existing element type and return the same collection element type. Array.exists, Array.for_all, List.exists, and List.for_all use the same element-to-bool predicate relationship and return bool. List.cons connects the head value and tail list. Set.add connects the old set element type, inserted value, and returned set. Map.set connects map key, provided key, map value, provided value, and returned map. Map.get returns exactly the value type stored by the map and accepts exactly the map key type.

let main =
  let names = Map.set (Map.empty ()) "ada" 1815 in
  Map.get names 1815
Typed map rejection. The map key type is string, so an int key cannot type check.
List.empty⁡:unit→′a  listList.cons⁡:′a→′a  list→′a  listList.head⁡:′a  list→′aList.tail⁡:′a  list→′a  listList.is_empty⁡:′a  list→boolList.length⁡:′a  list→intList.append⁡:′a  list→′a  list→′a  listList.reverse⁡:′a  list→′a  listList.map⁡:(′a→′b)→′a  list→′b  listList.filter⁡:(′a→bool)→′a  list→′a  listList.exists⁡:(′a→bool)→′a  list→boolList.for_all⁡:(′a→bool)→′a  list→bool\begin{aligned}\operatorname{List.empty}&: unit \rightarrow 'a\;list\\\operatorname{List.cons}&: 'a \rightarrow 'a\;list \rightarrow 'a\;list\\\operatorname{List.head}&: 'a\;list \rightarrow 'a\\\operatorname{List.tail}&: 'a\;list \rightarrow 'a\;list\\\operatorname{List.is\_empty}&: 'a\;list \rightarrow bool\\\operatorname{List.length}&: 'a\;list \rightarrow int\\\operatorname{List.append}&: 'a\;list \rightarrow 'a\;list \rightarrow 'a\;list\\\operatorname{List.reverse}&: 'a\;list \rightarrow 'a\;list\\\operatorname{List.map}&: ('a \rightarrow 'b) \rightarrow 'a\;list \rightarrow 'b\;list\\\operatorname{List.filter}&: ('a \rightarrow bool) \rightarrow 'a\;list \rightarrow 'a\;list\\\operatorname{List.exists}&: ('a \rightarrow bool) \rightarrow 'a\;list \rightarrow bool\\\operatorname{List.for\_all}&: ('a \rightarrow bool) \rightarrow 'a\;list \rightarrow bool\end{aligned}
List API. List operations preserve or transform element types according to their function arguments.
Set.empty⁡:unit→′a  setSet.add⁡:′a  set→′a→′a  setSet.has⁡:′a  set→′a→boolSet.length⁡:′a  set→int\begin{aligned}\operatorname{Set.empty}&: unit \rightarrow 'a\;set\\\operatorname{Set.add}&: 'a\;set \rightarrow 'a \rightarrow 'a\;set\\\operatorname{Set.has}&: 'a\;set \rightarrow 'a \rightarrow bool\\\operatorname{Set.length}&: 'a\;set \rightarrow int\end{aligned}
Set API. Set insertion is persistent and idempotent: adding an existing value returns the existing set.
Float.of_int⁡:int→floatFloat.to_int⁡:float→intString.concat⁡:string→string→stringString.length⁡:string→intString.split⁡:string→string→string  listto_string⁡:′a→stringfst⁡:(′a,′b)→′asnd⁡:(′a,′b)→′b\begin{aligned}\operatorname{Float.of\_int}&: int \rightarrow float\\\operatorname{Float.to\_int}&: float \rightarrow int\\\operatorname{String.concat}&: string \rightarrow string \rightarrow string\\\operatorname{String.length}&: string \rightarrow int\\\operatorname{String.split}&: string \rightarrow string \rightarrow string\;list\\\operatorname{to\_string}&: 'a \rightarrow string\\\operatorname{fst}&: ('a,'b) \rightarrow 'a\\\operatorname{snd}&: ('a,'b) \rightarrow 'b\end{aligned}
Scalar and string API. Scalar conversion and string helpers are typed in the same table as collection helpers.

The editor reuses the same signature table for completion details. That prevents the type checker, hover provider, and autocomplete provider from drifting into contradictory definitions of the standard library.

Map.empty⁡:unit→(′k,  ′v)  mapMap.set⁡:(′k,  ′v)  map→′k→′v→(′k,  ′v)  mapMap.get⁡:(′k,  ′v)  map→′k→′vMap.has⁡:(′k,  ′v)  map→′k→bool\begin{aligned}\operatorname{Map.empty}&: unit \rightarrow ('k,\;'v)\;map\\\operatorname{Map.set}&: ('k,\;'v)\;map \rightarrow 'k \rightarrow 'v \rightarrow ('k,\;'v)\;map\\\operatorname{Map.get}&: ('k,\;'v)\;map \rightarrow 'k \rightarrow 'v\\\operatorname{Map.has}&: ('k,\;'v)\;map \rightarrow 'k \rightarrow bool\end{aligned}
Map API. Map key and value variables remain connected across empty, set, get, and has.
  • print and println are checked through custom call logic: they accept int, float, or string and return unit.
  • to_string accepts any value and formats primitives, tuples, records, arrays, lists, sets, maps, and functions for output.
  • Tuple postfix projection reads any statically known element by zero-based index; fst and snd remain pair-specific helpers that reject non-pairs.
  • Array.append and List.append require matching element types and preserve operand order.
  • Array.reverse and List.reverse allocate reversed collections without changing element types.
  • Array.filter and List.filter require predicates returning bool and preserve the original element type.
  • Array.exists, Array.for_all, List.exists, and List.for_all require bool predicates and short-circuit when the result is known.
  • Array.iter and List.iter require callbacks returning unit.
  • Array.fold_left and List.fold_left keep accumulator type independent from element type.
  • Polymorphic builtins compile to uniform i32 functions at runtime; the checker preserves their static element, key, value, and callback relationships.