68
OCaml Returns Marwan Burelle Basics Mutable Exceptions OCaml Classics EPITA - Practical Programming 02 - Return of the Objective Caml Marwan Burelle [email protected] http://wiki-prog.infoprepa.epita.fr

EPITA - Practical Programming 02 - Return of the Objective Caml

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

EPITA - Practical Programming02 - Return of the Objective Caml

Marwan Burelle

[email protected]://wiki-prog.infoprepa.epita.fr

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Outline

1 OCaml BasicsFuntionsPrograms StructureCompiling !

2 OCaml And Imperative ProgrammingCan I Haz Loop ?Mutable Data

3 Exceptions

4 OCaml ClassicsPlay With IntListsBinary Tree

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

OCaml Basics

OCaml Basics

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

OCaml Quick Overview

• OCaml is functional and strongly typed language• It’s a variant of ML and thus provides type inference• It has a well founded semantics• It provides higher-order: function are first-class entity• It provide safe mutability (and thus imperative

features)• It provides an object model• It provides a powerful module sub-language• It can be interpreted (interactively or not), compiled

into bytecode or native code.

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Overview

1 OCaml BasicsFuntionsPrograms StructureCompiling !

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

In The Beginning Was Functions

The most basic expression is functional value

functional value(function x -> x + 1)

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Functions Can Be Applied

Applications(function x -> x + 1) 41

Applications can be reduced to closed value (here 42)

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Naming

Functional and closed values can be named for latter use

Naming valuelet f = function x -> x + 1 inlet res = f 20 in 2 * res

Naming can be local (as in previous example) or global

Global naminglet f = function x -> x + 1

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Function Definitions

Syntax: Function Definitionlet f = function x -> e(* e is an expression where x is free *)

Syntax: Sugarlet f = fun x -> elet f x = e

Syntax: Multiple Parameterslet f = function x -> function y -> x + ylet f = fun x -> fun y -> x + ylet f = fun x y -> x + ylet f x = function y -> x + ylet f x = fun y -> x + ylet f x y = x + y

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Curryfied Form

• In OCaml, like in λ−calculus, function always onlyone parameter

• Multiple parameters is obtain by returning a function

Application and Multiple Argumentslet r = (((fun x -> fun y -> x + y) 2) 40)let r’ = (fun x -> fun y -> x + y) 2 40

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Examples

Fact !let rec fact n =if n < 2 then 1else n * fact (n-1)

Fact with pattern matchinglet rec fact = function| 0 | 1 -> 1| n -> n * fact (n-1)

Fast Powerlet rec power x = function| 0 -> 1| p ->

(power (x*x) (p/2))* (if p mod 2 = 0 then 1 else x)

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Overview

1 OCaml BasicsFuntionsPrograms StructureCompiling !

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Where Are Double Semi-Colons ?

• Double semi-colons (;;) are useless• Unless: you’re using interactive mode or you’re using

toplevel expressions.• Don’t use double semi-colons !

Double semi-colons are uselesslet f a b = a + blet ref fibo = function| (0 | 1) as n -> n| n -> fibo (n-1) + fibo (n-2)

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

OCaml Code

• Toplevel (outside of any context) phrase must bedefinitions (names, types, modules . . . )

• Avoid toplevel expressions: they are meaningless anderror prone

• It is a good idea to build a main function to clarify theentry-point

A Simple Program(* The main function *)let main () =beginPrintf.printf "Hello World !\n";exit 0

end(* Starting Point *)let _ = main ()

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

What’s Wrong With Toplevel Expressions

Interactive Session# 1 + 1;;- : int = 2

But what happen if I do that in a program ?Example:

> cat foo.ml1 + 1;;> ocamlopt -o foo foo.ml> ./foo>

We got a program that seems to do nothing (but it may consumesome cycles for that . . . )

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Typical Structures of an OCaml Program

Program Structure(* definitions *)type t = BAD | GOODlet x = 42let f x = x + 1let to_bool = function| BAD -> false| GOOD -> true

(* Entry Point *)let main () =beginPrintf.printf "Hello World !\n";exit 0;

endlet _ = main ()

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Overview

1 OCaml BasicsFuntionsPrograms StructureCompiling !

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Choose Your Kind

• ocamlc: the bytecode compiler:• Bytecode is almost portable• Available on all POSIX system supported by gcc• Offer interesting debugging facilities• Produced code is (very) slow

• ocamlopt: the native compiler:• Produce fast code (from 5 to 15 time faster than

bytecode)• Easier interface with other language• Available only a limited set of architecture (x86, ARM,

Power, SPARC . . . )• Compilation is sometime slower

• ocamlc -cutom: produce a standalone bytecodebased program by combining the VM and thebytecode, you don’t want it.

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

Basic Compilation

foo.mllet main () =beginPrintf.printf "Hello World !\n";exit 0;

endlet _ = main ()

Example:> lsfoo.ml> ocamlopt -o foo foo.ml> lsfoo foo.cmi foo.cmx foo.ml foo.o> ./fooHello World !>

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

The Command Line

cmd.mllet main () =beginArray.iter (Printf.printf "| %S ") Sys.argv;Printf.printf "|\n";exit 0;

endlet _ = main ()

Example:> ocamlopt -o cmd cmd.ml> ./cmd a aa bb "a b c"| "./cmd" | "a" | "aa" | "bb" | "a b c" |>

OCaml Returns

Marwan Burelle

BasicsFuntions

Programs Structure

Compiling !

Mutable

Exceptions

OCaml Classics

ocamlbuild

• ocamlbuild is an automatic build system for OCaml• It’s more effective for multiple files project• For most basic example it can be used without any

configuration

Example:> lsfoo.ml> ocamlbuild foo.nativeFinished, 4 targets (0 cached) in 00:00:00.> ls_build foo.ml foo.native> ./foo.nativeHello World !> ocamlbuild -cleanFinished, 0 targets (0 cached) in 00:00:00.00:00:00 0 (0 ) STARTING> lsfoo.ml

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

OCaml And Imperative Programming

OCaml And ImperativeProgramming

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Pure Or Not. Pure, That’s The Question !

• Pure Functions are deterministic applications thatmap values (its argument) to a unique result.

• The behavior of a pure function is not affected byelements of the program state outside of its arguments,nor does it affect elements outside of its result.

• Theoretically, any possible behavior can be obtainedwith pure functions, mostly by passing and returningmemory states.

• OCaml choose the pragmatic approach: they breakpurity.

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Overview

2 OCaml And Imperative ProgrammingCan I Haz Loop ?Mutable Data

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Why Loop Are Not Functional

Example:x = 0;while x < 10 doprint(x);x = x + 1;

done

Can I do that as is in OCaml ?Fail Loop

let x = 0 inwhile x < 10 doPrintf.printf "%d\n" x;(* Now increase x ? *)let x = x + 1 (* OK *)in (* Now what ? *) ()

done

Fail !

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Basic For Loop

For the basic cases (bounded iteration) OCaml providessimple for loops without the need of any variables orside-effect operators:

For Loopfor i = 0 to 10 doPrintf.printf "%d\n" i

done

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

A Simple Example

Command Line With Looplet main () =beginfor i = 0 to (Array.length Sys.argv) - 1 doPrintf.printf "| %S " Sys.argv.(i)

done;Printf.printf "|\n";exit 0;

endlet _ = main ()

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Overview

2 OCaml And Imperative ProgrammingCan I Haz Loop ?Mutable Data

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Mutable ?

• Bounded iterations (for loops) aren’t sufficient toexpress all possible all algorithms (but, anyway,recursion is enough.)

• Sometimes we may also want to change the state ofmemory elements.

• But, since we’re using OCaml, we want to keep mostsafety properties of the language.

• Mutable entities should verify the followingproperties to be safe:• Existence: if a symbol exists, it references a valid

memory cell• Initialization: a memory cell always have a defined

value• Stability: the kind of the content of a memory cell

should not change

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

References

References are simplest mutable data in OCaml, it’s a kind ofsafe pointer.

references.mllet main () =beginlet r = ref 0 inPrintf.printf "r = ref %d\n" !r;r := 41;Printf.printf "r = ref %d\n" !r;r := !r + 1;Printf.printf "r = ref %d\n" !r;exit 0;

endlet _ = main ()

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Some Examples

Basic While Looplet r = ref 0 inwhile !r < 10 doPrintf.printf "%d\n" !r;r := !r + 1;

done

incr and decr(* Already available in Pervasive module *)let incr r = r := !r + 1let decr r = r := !r - 1

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Some Examples

Fact !let fact n =if n < 2 then 1elsebeginlet r = ref 1 infor i = n downto 1 dor := !r * i;

done;!r

end

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Closures

closures.mllet f1 = Printf.printf "f1\n"let f2 () = Printf.printf "f2\n"let f3 = fun _ -> Printf.printf "f3\n"let f4 = Printf.printf "f4 (1)\n";fun _ -> Printf.printf "f4 (2)\n"

let main () =Printf.printf "\nMain\n";f1; f2 (); f3 (); f4 (); exit 0

let _ = main ()

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Closures

closures.ml> ./closures.nativef1f4 (1)

Mainf2f3f4 (2)

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Closures And References

next.mllet next =let r = ref 0 infun () ->r := !r + 1;!r

let main () =beginfor i = 1 to 10 doPrintf.printf "%d " (next ())

done;Printf.printf "\n";exit 0;

endlet _ = main ()

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Closures And References

Example:

> ocamlbuild next.nativeFinished, 4 targets (0 cached) in 00:00:00.> ./next.native1 2 3 4 5 6 7 8 9 10>

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Arrays And Strings

Arrays and strings are mutable !mutable_array.ml

let main () =let t = Array.make 3 0 inArray.iteri (Printf.printf "t.(%d) = %d ") t;Printf.printf "\n";t.(1) <- 42;Array.iteri (Printf.printf "t.(%d) = %d ") t;Printf.printf "\n";exit 0

let _ = main ()

Example:

> ./mutable_array.nativet.(0) = 0 t.(1) = 0 t.(2) = 0

t.(0) = 0 t.(1) = 42 t.(2) = 0

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Arrays And Strings (2)

mutable_strings.mllet main () =beginlet s = "abcd" inPrintf.printf "%S\n" s;s.[3] <- ’e’;Printf.printf "%S\n" s;exit 0;

endlet _ = main ()

Example:

> ocamlbuild mutable_strings.nativeFinished, 4 targets (0 cached) in 00:00:00.> ./mutable_strings.native"abcd""abce"

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Records

OCaml provides traditional records. Record’s field can bemarked as mutable.

Example of Recordslet next = let c = ref 0 in fun _ -> incr c;!c

type person = {name : string;uniq_id : int;mutable visit_count : int;

}

let new_person n ={ name=n; uniq_id= next (); visit_count=0 }

let visiting p =p.visit_count <- p.visit_count + 1

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

More On Records

Fun With Recordstype state = NIL | MODIFIED | EXCLUSIVE | SHARED | INVALIDtype cache_line = {addr : nativeint;content : nativeint array;mutable cache_state : state;

}

let new_line addr = {addr = addr; cache_state = NIL;content = Array.make 16 (0n);

}

let invalidate addr lines = Array.iter(function| { cache_state = SHARED } as l

when l.addr = addr -> l.cache_state <- INVALID| _ -> ()

) lines

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Smart Copy

Smart Record Copytype entity = {id : int;mutable x: float; mutable y: float; mutable z: float;mutable dx: float; mutable dy: float; mutable dz: float;

}

let base_entity = {id = -1;x = 0.; y = 0.; z = 0.;dx = 0.; dy = 0.; dz = 0.;

}

let new_entity ={ base_entity with id = next (); }

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Beware When Copying

records.mltype t = {a : int ref;mutable b : int;

}let r = { a = ref 0; b = 0 }let r’ = { r with b = 1; }let main () =beginr.a := 42; r.b <- 42;Printf.printf "r’.a = ref %d\nr’.b = %d\n"!(r’.a) r’.b;

endlet _ = main ()

Example:

> ./records.nativer’.a = ref 42r’.b = 1

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Beware When Copying

records.mltype t = {a : int ref;mutable b : int;

}let r = { a = ref 0; b = 0 }let r’ = { r with b = 1; }let main () =beginr.a := 42; r.b <- 42;Printf.printf "r’.a = ref %d\nr’.b = %d\n"!(r’.a) r’.b;

endlet _ = main ()

Example:

> ./records.nativer’.a = ref 42r’.b = 1

OCaml Returns

Marwan Burelle

Basics

MutableCan I Haz Loop ?

Mutable Data

Exceptions

OCaml Classics

Records And References

Interactive Session# ref 0;;- : int ref = {contents = 0}

References are, in fact, syntactic sugar on records.

Theoretical Definitions of type reftype ’a ref = { mutable contents : ’a }

Some consequences

Alternative syntaxlet x = ref 0 inx.contents <- 1; (* same as x := 1 *)(x.contents = !x) (* always true *)

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Exceptions

Exceptions

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Exceptions ?

• Exceptions mechanism allows programmer to triggerspecific behavior in some particular cases.

• Exceptions are used to get out of the normal flow ofexecutions: when an exception is raised, the programescapes the current call-stack until the exception iscatched or the program dies.

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Declaring Exceptions

• You can define your own exceptions• An exception as the same syntax as data-type tag and

can have parameters• All the exceptions have the exn and can be used as

value.Declaring exception

(* A Simple exception without parameter *)exception MyFstException

(* With two parameters: an int and a string *)exception WrongParameters of int * string

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Exception: Without Catching

Entry Point

1st Function

2nd Function

3rd Function

exception

Program Boundary

call

call

call

Error: uncaught exception

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Raising Exceptions

fail.mlexception MyFailure of int * int

let thrd_fun i j =beginPrintf.printf "3rd function\n%!";ignore (raise (MyFailure(i,j)));Printf.printf "After raise\n%!";

endlet snd_fun i j =Printf.printf "2nd function\n%!";thrd_fun i j

let fst_fun i j =Printf.printf "1st function\n%!";snd_fun i j

let main () =fst_fun 42 666

let _ = main ()

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Raising Exceptions

fail.ml> ./fail.native1st function2nd function3rd functionFatal error: exception Fail.MyFailure(42, 666)

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Using Predefined Exception

List.assoclet rec assoc x = function| [] -> raise Not_found| (k,v)::_ when x=k -> v| _::t -> assoc x t

failwith and invalid_arglet failwith s = raise (Failure s)let invalid_arg s = raise (Invalid_argument s)

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Catching Exceptions

Entry Point

1st Function

2nd Function

3rd Function

exception

Program Boundary

call

call

call

try … with

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Catching Exceptions

fail2.mlexception MyFailure of int * int

let thrd_fun i j =beginPrintf.printf "3rd function\n%!";ignore (raise (MyFailure(i,j)));Printf.printf "After raise\n%!";

endlet snd_fun i j =Printf.printf "2nd function\n%!";thrd_fun i j

let fst_fun i j =Printf.printf "1st function\n%!";try snd_fun i j with| MyFailure (x,y) ->Printf.eprintf "catched MyFailure (%d,%d)\n%!" x y

let main () =fst_fun 42 666

let _ = main ()

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml Classics

Catching Exceptions

fail.ml> ./fail2.native1st function2nd function3rd functionFatal error: exception Fail.MyFailure(42, 666)

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

OCaml Classics

OCaml Classics

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Overview

4 OCaml ClassicsPlay With IntListsBinary Tree

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Example

fact and fibo(* Factorial (tail recursive) *)let fact n =let rec aux a = function| 0 | 1 -> a| n -> aux (n*a) (n-1)

in aux 1 n

(* Fibonacci (naive version) *)let rec fibo = function| (0|1) as x -> x| n -> fibo (n-1) + fibo (n-2)

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Example

Smarter fibo(* Fibonacci (linear-tail recursive version) *)let linear_fibo n =let rec aux f1 f2 x =if x = n then f1else aux (f1 + f2) f1 (x + 1)

inmatch n with| 0 | 1 -> n| _ when n < 0 -> -1| _ -> aux 1 0 1

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Example

Power And Square Rootlet rec power x = function| 0 -> 1 | 1 -> x| p -> (power (x*x) (p/2))

* (if p mod 2 = 0 then 1 else x)

let rec numbits a = function| 0 -> a| n -> numbits (a+1) (n lsr 1)

let int_sqrt n =let init = (1 lsl (1+((numbits 0 n)-1)/2)) inlet rec aux x =let y = (x + n/x)/2 inif y >= x then xelse aux y

in aux init

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Overview

4 OCaml ClassicsPlay With IntListsBinary Tree

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Example

Length And nth(* List.length *)let length l =let rec aux len = function| [] -> len| a::l -> aux (len + 1) l

in aux 0 l

(* List.nth *)let nth l n =(* Avoid stupid calls *)if n < 0 then invalid_arg "List.nth" elselet rec nth_aux n = function| [] -> failwith "nth"| a::l ->if n = 0 then a else nth_aux (n-1) l

in nth_aux n l

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Example

Rev And Append(* List.rev_append *)let rec rev_append l1 l2 =match l1 with| [] -> l2| a :: l -> rev_append l (a :: l2)

(* List.rev *)let rev l = rev_append l [](* List.append or @ *)let append l1 l2 =rev_append (rev l1) l2

(* List.flatten *)let rec flatten = function

[] -> []| l::r -> l @ flatten r

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Example

Lists iterators(* List.map *)let rec map f = function| [] -> []| a::l -> let r = f a in r :: map f l

(* List.iter *)let rec iter f = function| [] -> ()| a::l -> f a; iter f l

(* List.rev_map *)let rev_map f l =let rec rmap_f accu = function| [] -> accu| a::l -> rmap_f (f a :: accu) l

inrmap_f [] l

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Example

Folds(* List.fold_left *)let rec fold_left f accu l =match l with| [] -> accu| a::l -> fold_left f (f accu a) l

(* List.fold_right *)let rec fold_right f l accu =match l with| [] -> accu| a::l -> f a (fold_right f l accu)

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Overview

4 OCaml ClassicsPlay With IntListsBinary Tree

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Example

Binary Treetype ’a tree =| Empty| Node of ’a tree * ’a * ’a tree

(* A size function with all special cases *)let rec size = function| Empty -> 0| Node (Empty, _, Empty) -> 1| Node (child, _, Empty)| Node (Empty, _, child)-> 1 + size child

| Node (left, _, right)-> 1 + size left + size right

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Example

Depth First Traversallet rec height = function| Empty -> -1| Node (left, _, right)-> 1 + max (height left) (height right)

let rec prefix accu = function| Empty -> accu| Node (left, k, right)-> k :: prefix (prefix accu right) left

let rec prefix_print print = function| Empty -> ()| Node (left, k, right) ->print k;prefix_print print left;prefix_print print right

OCaml Returns

Marwan Burelle

Basics

Mutable

Exceptions

OCaml ClassicsPlay With Int

Lists

Binary Tree

Example

Breadth First Traversallet breadth_first print t =let q = Queue.create () inbeginif t <> Empty then Queue.push t q;Queue.push Empty q;while not (Queue.is_empty q) domatch Queue.take q with| Empty ->Printf.printf "\n";if not (Queue.is_empty q) thenQueue.push Empty q;

| Node (left,k,right) ->print k;if t <> Empty then Queue.push left q;if t <> Empty then Queue.push right q;

done;end