Caml provides the following data structures: numbers (integers or floating point numbers), booleans, characters, character strings, arrays, lists, references. In addition, some library modules define extra abstract data types on top of these basic ones (in particular sets and streams, see below).
If none of these predefined data structures is suitable to model your data, you have to define your own data structures, with a type definition.
Table of contents:
Integers and floating point numbers correspond to the basic arithmetic capabilities provided by the hardware. Hence these numbers are easy to use but have some limitations, either in accuracy or range. Caml also provides numbers that support exact arithmetic operations: the arbitrary precision arithmetic package implements rational numbers, whose size may be as large as several thousand decimal digits. This package is a bit harder to use, than built-in arithmetics.
int
and get usual operations: +, -, *, / (that returns
the integer quotient of the division).
#1 + 2 * 3;; - : int = 7
Other operations:
print_int
.
lsl
(logical shift left), lsr
(logical
shift right), asr
(arithmetic shift right),
land
(et), lor
(or), lxor
(or
exclusive), lnot
(non).
int
: int_of_string
,
int_of_float
, int_of_char
.
int
.
float
and get the usual operations (with an extra
.
suffix): +.
, -.
,
*.
, /.
#1.0 +. 2.0 *. 3.0;; - : float = 7.0
Other operations:
print_float
.
sin
, cos
, tan
,
asin
, acos
, atan
,
atan2
, exp
, log
,
**
.
float
:
float_of_string
, float_of_int
.
float
.
Characters are the elements of the type char
. They are
enclosed by the `
symbol:
#`a`;; - : char = `a` #`\n`;; - : char = `\n` #`\\`;; - : char = `\\`
Other operations:
print_char
.
char
: char_of_int
,
char_for_read
char
.
Character strings are the elements of the type string
;
these are ordered sequels of letters. The size of a string is
definitively defined when the string is created. Elements of a string
may be updated.
"
symbols.
#let s = "ok";; s : string = "ok"
#let s1 = make_string 2 `1`;; s1 : string = "11" #s1.[1] <- `2`;; - : unit = () #s1;; - : string = "12"
str.[i]
returns
the character number i
of the string str
.
#let s = "ok";; s : string = "ok" #s.[0];; - : char = `o` #s.[1];; - : char = `k`
str.[i] <- char
,
writes the character char
into the number
i
location of the string str
:
#let s = "ok";; s : string = "ok" #s.[1] <- `h`;; - : unit = () #s;; - : string = "oh"
for
'' loop to walk through a string.
#let s = "ok";; s : string = "ok" #for i = 0 to string_length s - 1 do print_char s.[i]; print_string " " done;; o k - : unit = ()
print_string
.
string_length
.
blit_string
.
sub_string
.
string_of_int
,
string_of_float
, string_of_bool
,
string_for_read
, char_for_read
.
^
''.
string
.
Arrays or vectors are the elements of the
type 'a vect
; these are ordered sequels of elements of
type 'a
. The size of an array is definitively defined
when the array is created. Elements of an array may be updated.
;
and enclosed by the symbols
[|
and |]
.
#let v = [| 1; 2; 3 |];; v : int vect = [|1; 2; 3|]
#let v1 = make_vect 2 "Hello";; v1 : string vect = [|"Hello"; "Hello"|] #v1.(1) <- "World!";; - : unit = () #v1;; - : string vect = [|"Hello"; "World!"|]Beware: the initial value is physically shared by all the elements of the vector being defined. If this initial value is a mutable value, this semantics may be surprising for the beginner. This appears in particular for matrices, defined as vectors of vectors: a careless initialization returns a matrix with a unique raw vector, shared by all the raws.
tab.(i)
returns the element number i
of the
array tab
.
#let v = [| 1; 2; 3 |];; v : int vect = [|1; 2; 3|] #v.(0);; - : int = 1
tab.(i) <- elem
,
writes the value elem
into the number
i
location of the array tab
.
#let v = [| 1; 2; 3 |];; v : int vect = [|1; 2; 3|] #v.(1) <- 0;; - : unit = () #v;; - : int vect = [|1; 0; 3|]
for
'' loop to walk through an array.
#let v1 = [|"Hello"; "World!"|];; v1 : string vect = [|"Hello"; "World!"|] #for i = 0 to vect_length v1 - 1 do print_string v1.(i); print_string " " done;; Hello World! - : unit = ()
for
loop or the do_vect
functional.
vect_length
.
blit_vect
.
sub_vect
.
concat_vect
.
map_vect
, do_vect
,...
vect
.
Lists are the elements of the type 'a list
; these are
ordered sequels of elements of type 'a
. The size of a
list is dynamically modified, since elements can be added if
necessary. A list is a recursive data structure: it is either empty,
and then it is []
(say it ``nil''), or it is not empty
and then it is built with an ``head'' of list, put in front of the
``rest'' or queue of the list. A non empty list is built by the
application of the list constructor ::
(an infix operator
read as ``conse''). A non empty list with head ``x'' and queue ``rest'' is thus
x :: rest
. Elements of a list cannot be updated.
[
and ]
.
#let l = [ 1; 2; 3 ];; l : int list = [1; 2; 3]
#match l with x :: _ -> x | _ -> raise (Failure "empty");; - : int = 1 #let rec nth n l = match l with [] -> raise (Failure "nth") | x :: l -> if n <= 0 then x else nth (n - 1) l;; nth : int -> 'a list -> 'a = <fun> #nth 2 l;; - : int = 3
#let l1 = [];; l1 : 'a list = [] #let l2 = "World!" :: l1;; l2 : string list = ["World!"] #let l3 = "Hello" :: l2;; l3 : string list = ["Hello"; "World!"] #let rec interval n m = if n > m then [] else n :: interval (n + 1) m;; interval : int -> int -> int list = <fun> #interval 3 7;; - : int list = [3; 4; 5; 6; 7]
#let rec print_list = function [] -> () | x :: l -> print_string x; print_string " "; print_list l in print_list l3;; Hello World! - : unit = ()
do_list
.
list_length
.
@
''.
map
, it_list
,
list_it
, ...
[]
or pattern
x :: lf
.
list
.
Booleans are the elements of the type
bool
; these are values of boolean logic.
true
and false
. These are the results of
tests.
#1 = 2;; - : bool = false #1 <= 2;; - : bool = true
Booleans get infix operations
``or'' and ``and'' of mathematical logic (respectively denoted by
||
and &&
),
and the negation (function not
).
#(1 = 2) || not (1 <= 2);; - : bool = false #1 = 2 || not 1 <= 2;; - : bool = false
Other operations:
print_bool
where
let print_bool b = print_string (string_of_bool b);;
.
string_of_bool
, bool_of_string
where
let bool_of_string = function "true" -> true | "false" -> false | _ -> raise (Invalid_argument "bool_of_string");;
``void'' is the only element of the type
unit
. It is denoted by ()
(say it ``void''),
and means the dummy result and argument of procedures.
#print_string "Hello World!";; Hello World!- : unit = () #print_newline();; - : unit = ()
References are the elements of the
type 'a ref
; these are memory locations that contain a
value of type 'a
. They are used in imperative programming
to implement accumulators.
The element stored in the location may be modified, that is replaced
by another value of the same type.
ref
is applied to its inial contents.
#let r = ref 1;; r : int ref = ref 1
!
(say it ``deref''). So !r
returns the
contents of the reference r
.
#!r;; - : int = 1
r := elem
,
writes the value elem into the reference r
.
#r := 0;; - : unit = () #r;; - : int ref = ref 0
Using a reference and a loop, you can write an imperative version of the factorial function:
#let fact x = let result = ref 1 in for i = 1 to x do result := i * !result done; !result;; fact : int -> int = <fun> #fact 10;; - : int = 3628800
incr
, decr
.
ref
.
Pairs of a value of type
'a
, and of a value of type 'b
are the
elements of the Cartesian product of 'a
and
'b
,
denoted as 'a * 'b
in Caml.
#let p = (1, 2);; p : int * int = 1, 2
#let first = function (x, y) -> x;; first : 'a * 'b -> 'a = <fun> #first p;; - : int = 1
pair
.
Other data structures available are system dependent. For instance, the Caml Light system offers:
Contact the author Pierre.Weis@inria.fr