[hanauma] 101 > ocaml
Objective Caml version 3.08.0
#
# 2 ;;
- : int = 2
#
Antwort: definierte Variable (keine -
), Typ
(int
), Ergebnis (2
)
# let x=2;;
val x : int = 2
#
Antwort: definierte Variable (x
), Typ
(int
), Ergebnis (2
)
# let square x= x*x;; val square : int -> int =Antwort: definierte Variable (#
square
), Typ
(int -> int
), Ergebnis (<fun>
)
(*
und *)
, können
rekursiv geschachtelt werden.
# (* nur ein (* geschachtelter *) Kommentar *) ;;
#
.ml
# #use "filename";;
M-x run-caml
caml-mode
caml-eval-phrase
) # (1=2);; - : bool = false # 42;; - : int = 42 # 3.1415926536;; - : float = 3.1415926536 # "resistentialism";; - : string = "resistentialism" # 'x';; - : char = 'x' # ();; - : unit = () #
bool
boolesche Werteint
Maschinenintegers mit den üblichen
Operationenfloat
IEEE 754 standard double precision (64
bits) Floating Point mit +.
,
-.
, *.
, /.
string
mit Verkettung ^
char
unit
(keine Operationen)# let square x = x * x ;; val square : int -> int = <fun> # square 42;; - : int = 1764 # let average x y = (x + y) / 2;; val average : int -> int -> int = <fun> # average 21 63;; - : int = 42 # let paren x = "("^x^")";; val paren : string -> string = <fun> # let rec power x n = if n=0 then 1 else x * power x (n-1) ;; val power : int -> int -> int = <fun> #
t1 -> t2
Funktionstypen
average
)let rec
celsius2fahrenheit
und Umkehrung
fahrenheit2celsius
int2binary : int -> string
int2base : int -> int -> string
isbntest
For the purposes of this document, we will consider the ISBN 0-13-190190-7 which is the ISBN for Number Theory with Applications by James A. Anderson and James M. Bell.
To determine the check digit for this Internation Standard Book Number, follow the below steps.
Step 1: Mutliply all nine assigned digits by weighted values. The weighted values are 1 for the first digit from the left, 2 for the second digit, three for third digit, etc.
1*0 + 2*1 + 3*3 + 4*1 + 5*9 + 6*0 + 7*1 + 8*9 + 9*0 = 139
Step 2: ISBN uses (mod 11) to determine the check digit.
139 = 7 (mod 11)
To determine if a check digit in an ISBN number is valid multiply all 10 digits by weighted values to get a value t, and t = 0(mod 11). In our case 1*0 + 2*1 + 3*3 + 4*1 + 5*9 + 6*0 + 7*1 + 8*9 + 9*0 + 10*7 = 0(mod 11).
The below applet allows a person to validate an ISBN number. If the ISBN given is invalid, the valid check digit for the 9 assigned digits will be provided. Enter the ISBN in the first text field and then press the button titled "Verify ISBN Number".
# [1;2;3;4] ;;
- : int list = [1; 2; 3; 4]
# ["The"; "quick"; "brown"; "fox"];;
- : string list = ["The"; "quick"; "brown"; "fox"]
# [[1; 1]; [0; 1]];;
- : int list list = [[1; 1]; [0; 1]]
# [] ;;
- : 'a list = []
# 1 :: 2 :: 3 :: 4 :: [];;
- : int list = [1; 2; 3; 4]
# let cons x xs = x :: xs ;;
val cons : 'a -> 'a list -> 'a list = <fun>
@
, eine polymorphe Funktion
# [2; 4] @ [1; 3; 5];;
- : int list = [2; 4; 1; 3; 5]
# let number x = match x with 0 -> "null" | 1 -> "eins" | 2 -> "zwei" | 3 -> "drei" | _ -> "ganz viel" ;; val number : int -> -> string = <fun> # number 2;; - : string = "zwei" #
# let head (x :: xs) = x;; Warning: this pattern-matching is not exhaustive. Here is an example of a value that is not matched: [] val head : 'a list -> 'a = <fun> # let tail (x :: xs) = xs;; Warning: this pattern-matching is not exhaustive. Here is an example of a value that is not matched: [] val tail : 'a list -> 'a list =#
# let rec mul17 xs =
match xs with
[] -> []
| y :: ys -> 17*y :: mul17 ys ;;
val mul3 : int list -> int list = <fun>
#
# let rec greater7 xs =
match xs with
[] -> []
| x :: xs -> if x > 7 then x :: greater7 xs else greater7 xs;;
val greater7 : int list -> int list = <fun>
#
# let rec sum xs =
match xs with
[] -> 0
| x :: xs -> x + sum xs ;;
val sum : int list -> int = <fun>
# let add x y = x + y ;; val add : int -> int -> int = <fun> # add 17 4 ;; - : int = 21 # let add4 = add 4 ;; val add4 : int -> int =# add4 17 ;; - : int = 21 #
# fun x y -> x + y ;; - : int -> int -> int = <fun> # let add4 = fun x y -> x + 4 ;; val add4 : int -> int =# add4 17 ;; - : int = 21 #
# let rec map f xs = match xs with [] -> [] | x :: xs -> f x :: map f xs ;; val map : ('a -> 'b) -> 'a list -> 'b list = <fun> # map add4 [13; 15; 17] ;; - : int list = [17; 19; 21] #
# let rec fold c n xs = match xs with [] -> n | x :: xs -> c x (fold c n xs) ;; val fold : ('a -> 'b -> 'b) -> 'b -> 'a list -> 'b = <fun> # fold add 0 [13; 15; 17] ;; - : int = 45 #
# let rec filter p xs = match xs with [] -> [] | x :: xs -> if p x then x :: filter p xs else filter p xs ;; val filter : ('a -> bool) -> 'a list -> 'a list = <fun> # filter (fun x -> x > 14) [13; 15; 17] ;; - : int list = [15; 17] #
List.map : ('a -> 'b) -> 'a list -> 'b list
List.fold_right : ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b
List.filter : ('a -> bool) -> 'a list -> 'a list
List.
verwenden
# let compose f g x = f (g x) ;; val compose : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun> # compose add4 add4 2;; - : int = 10 #
# let flip f x y = f y x ;; val flip : ('a -> 'b -> 'c) -> 'b -> 'a -> 'c = <fun> # flip cons [13; 15; 17] 11 ;; - : int list = [11; 13; 15; 17] #
# let twice f x = f (f x) ;; val twice : ('a -> 'a) -> 'a -> 'a = <fun> # twice (fun x -> x * 2) 7 ;; - : int = 28 # twice twice (fun x -> x + 1) 2 ;; - : int = 6 #
List.fold_right
für
map
filter
List.map
für
List.filter
für
(* derivativeh : float -> (float -> float) -> float -> float *) let derivativeh dx f x = ... let derivative = derivativeh 0.0001 let g = derivative fsquare
(* integrate : float -> (float -> float) -> float -> float -> float *) let integrateh dx f x0 x = ... let integrate = integrateh 0.0001 let h = integrate fsquare 0.0
lu : 'a -> 'a list
lb : 'a list -> ('a -> 'b list) -> 'b list
lj : 'a list list -> 'a list
cu : 'a -> ('a -> unit) -> unit
cb : (('a -> unit) -> unit) -> ('a -> ('b ->
unit) -> unit) -> ('b -> unit) -> unit
# let p1 = (1, 2) ;; val p1 : int * int = (1, 2) # let p2 = ("mal zwei", (fun x -> x * 2), (17+4)*2 = 42) ;; val p2 : string * (int -> int) * bool = ("mal zwei", <fun>, true)
# let (x, y) = (17, 4) ;; val x : int = 17 val y : int = 4 # let swap (x, y) = (y, x) ;; val swap : 'a * 'b -> 'b * 'a = <fun> #
zip : 'a list -> 'b list -> ('a * 'b) list unzip : ('a * 'b) list -> ('a list * 'b list) uncurry : ('a -> 'b -> 'c) -> ('a * 'b -> 'c) curry : ('a * 'b -> 'c) -> ('a -> 'b -> 'c)
# type ratio = {num: int; denum: int};; type ratio = { num : int; denum : int; } # let b = {num=7; denum=8} ;; val b : ratio = {num = 7; denum = 8}
# let rmult x y = { num= x.num * y.num; denum= x.denum * y.denum};; val rmult : ratio -> ratio -> ratio = <fun> # rmult b {num=5; denum=6} ;; - : ratio = {num = 35; denum = 48} #
# let rdiv {num=x1; denum=y1} {num=x2; denum=y2} =
{num=x1*y2; denum=x2*y1} ;;
val rdiv : ratio -> ratio -> ratio = <fun>
#
rectLength : rect -> float rect2polar : rect -> polar addCoor : rect -> rect -> rect scalarProd : rect -> rect -> float
# type number = Int of int | Float of float | Error;; type number = Int of int | Float of float | Error # [Int 5; Float 31.4; Error] ;; - : number list = [Int 5; Float 31.4; Error]
Int
, Float
, Error
)
# let nsquare num =
match num with
Int i -> Int (i*i)
| Float f -> Float (f*.f)
| Error -> Error
;;
val rdiv : ratio -> ratio -> ratio = <fun>
#
# type color = Rot | Grün | Gelb ;;
#
num
# type 'a ltree = Leaf of 'a | Branch of 'a ltree * 'a ltree ;; type 'a ltree = Leaf of 'a | Branch of 'a ltree * 'a ltree # let t = Branch (Leaf 'a', Branch (Leaf 'm', Leaf 'z')) ;; val t : char ltree = Branch (Leaf 'a', Branch (Leaf 'm', Leaf 'z')) #
# let rec lmap f t = match t with Leaf x -> Leaf (f x) | Branch (l, r) -> Branch (lmap f l, lmap f r) ;; val lmap : ('a -> 'b) -> 'a ltree -> 'b ltree = <fun> # lmap (String.make 1) t;; - : string ltree = Branch (Leaf "a", Branch (Leaf "m", Leaf "z")) #
'a ltree -> 'a list
'a ltree ltree -> 'a ltree
'a ltree -> ('a -> 'b) -> ('b * 'b -> 'b) -> 'b
analog zur fold
Funktion auf Listen.
Cons
und
Nil
, so dass der folgende Ausdruck typkorrekt
ist.
Cons (5, Cons (true, Cons ("hello", Nil)))Verschärfte Version: Wähle die Definition so, dass zusätzlich der folgende Ausdruck nicht typkorrekt ist.
Cons (5, Cons (true, Cons ("hello", (Cons (), Nil))))
# type exp =
Const of float
| Var of string
| Add of exp * exp
| Mul of exp * exp
| Div of exp * exp
| Sin of exp ;;
# type exp =
Const of float
| Var of string
| Add of exp * exp
| Mul of exp * exp
| Div of exp * exp
| Sin of exp
#
(* ev : (string * float) list -> exp -> float *) let dd env e = ...Dabei ist
env
eine Liste von Paaren aus
Variablennamen und Wert.
(* dd : string -> exp -> exp *) let dd var e = ...ggf. ist noch eine Vereinfachungsfunktion notwendig, um zB. Multiplikationen mit Null zu eliminieren.
type 'a ref (* Zeiger auf Werte vom Typ 'a *) (!) : 'a ref -> 'a (* Dereferenzieren *) (:=) : 'a ref -> 'a -> unit (* Überschreiben *)
let ifac n = let acc = ref 1 in let rec loop i = if i <= 0 then !acc else begin acc := !acc * i; loop (i-1) end in loop n ;; val ifac : int -> int = <fun> # ifac 5;; - : int = 120
# type point2d = { mutable x : float ; mutable y : float };; # let translate p dx dy = begin p.x <- p.x +. dx; p.y <- p.y +. dy; end;; val translate : point2d -> float -> float -> unit = <fun>
# type pointmethods = { move : float -> float -> unit; scale : float -> unit; getx : unit -> float; gety : unit -> float; };; # let newpoint x y = let p = { x=x; y=y; } in { move = (fun dx dy -> (p.x <- p.x +. dx; p.y <- p.y +. dy)); scale = (fun d -> (p.x <- d*.p.x; p.y <- d*.p.y)); getx = (fun () -> p.x); gety = (fun () -> p.y); } ;; val newpoint : float -> float -> pointmethods = <fun> # let p = newpoint 20. 30.;; val p : pointmethods = {move = <fun>; scale = <fun>; getx = <fun>; gety = <fun>} # p.scale 0.1;; - : unit = () # p.getx ();; - : float = 2. # p.gety ();; - : float = 3.
.ml
let int2base v b = ... let main () = let base = int_of_string Sys.argv.(1) in let valu = int_of_string Sys.argv.(2) in let result = int2base valu base in print_string result; print_newline (); exit 0;; main ()Compilieren geschieht mit
ocaml convert.ml -o convertbzw mit dem Native code compiler
ocamlopt convert.ml -o convertBeide Dateien sind direkt ausführbar:
> ./convert 16 10006 2716 > ./convert 3 10000 111201101
ModulName.ml
enthält die
Definitionen für Modul ModulName
ModulName.mli
enthält die
Schnittstellendefinition (die Signatur) von Modul
ModulName
ocamlc -o Programmname Modul1.cmo Modul2.cmo Modul3.cmoReihenfolge beachten!
type t val make : string -> t val extract : t -> string val concat : t -> t -> tDatei HTMLStrings.ml enthält
type t = string let htmlentities s = s (* fix this *) let htmldecode s = s (* fix this *) let make s = htmlentities s let extract s = htmldecode s let concat s1 s2 = s1 ^ s2Nach außen hin ist
t
ein abstrakter Typ, dh. seine
Definition ist nicht sichtbar. Ebenso sind die Funktionen
htmlentities
und htmldecode
nicht nach außen
hin sichtbar.
module HTMLStrings = struct type t = string let htmlentities s = s (* fix this *) let htmldecode s = s (* fix this *) let make s = htmlentities s let extract s = htmldecode s let concat s1 s2 = s1 ^ s2 end;;sowie für eine Signaturdefinition
module type HTMLSTRINGS = sig type t val make : string -> t val extract : t -> string val concat : t -> t -> t end;;
module AbstractHTMLStrings = (HTMLStrings : HTMLStrings) ;;
# type comparison = Less | Equal | Greater;; type comparison = Less | Equal | Greater # module type ORDERED_TYPE = sig type t val compare: t -> t -> comparison end;; module type ORDERED_TYPE = sig type t val compare : t -> t -> comparison end # module Set = functor (Elt: ORDERED_TYPE) -> struct type element = Elt.t type set = element list let empty = [] let rec add x s = match s with [] -> [x] | hd::tl -> match Elt.compare x hd with Equal -> s (* x is already in s *) | Less -> x :: s (* x is smaller than all elements of s *) | Greater -> hd :: add x tl let rec member x s = match s with [] -> false | hd::tl -> match Elt.compare x hd with Equal -> true (* x belongs to s *) | Less -> false (* x is smaller than all elements of s *) | Greater -> member x tl end;; module Set : functor (Elt : ORDERED_TYPE) -> sig type element = Elt.t type set = element list val empty : 'a list val add : Elt.t -> Elt.t list -> Elt.t list val member : Elt.t -> Elt.t list -> bool endVerwendung:
ORDERED_TYPE
Set
auf diese Struktur# module OrderedString = struct type t = string let compare x y = if x = y then Equal else if x < y then Less else Greater end;; module OrderedString : sig type t = string val compare : 'a -> 'a -> comparison end # module StringSet = Set(OrderedString);; module StringSet : sig type element = OrderedString.t type set = element list val empty : 'a list val add : OrderedString.t -> OrderedString.t list -> OrderedString.t list val member : OrderedString.t -> OrderedString.t list -> bool end # StringSet.member "bar" (StringSet.add "foo" StringSet.empty);; - : bool = false
OrderedInt
sowie IntSet
.STRINGSET
, so dass StringSet : STRINGSET
gilt.
STRINGSET
. Zum Beispiel Einlesen einer Liste
von Worten von einer Datei (ein Wort pro Zeile) und dann
Test, ob das Wort auf der Kommandozeile in dieser Menge
enthalten ist.
FastSet
des Funktors von ORDERED_TYPE
, so dass dessen
Anwendung auf StringSet
wieder eine Struktur
vom Typ STRINGSET
liefert. Kode und
Funktionalität der Anwendung sollte unverändert bleiben.