Kurz: Ein module bündelt Typen und Funktionen; eine sig legt die öffentliche Schnittstelle fest:
Teil des Kurses OCaml
Strings, Char und Bytes
let () =
let s = "Hallo OCaml" in
Printf.printf "%d %s %s\n" (String.length s) (String.uppercase_ascii s) (String.lowercase_ascii s);
Printf.printf "%c %s\n" s.[0] (String.sub s 6 5);
Printf.printf "%b %b\n" (String.contains s 'O') (String.starts_with ~prefix:"Hal" s);
Printf.printf "%s\n" (String.concat "-" ["a"; "b"; "c"]);
List.iter print_endline (String.split_on_char ' ' s);
Printf.printf "[%s]\n" (String.trim " x ");
Printf.printf "%s\n" (String.map (fun c -> if c = 'a' then '4' else c) s);
Printf.printf "%d\n" (String.index s 'O');
print_endline (String.make 3 '*');
String.iter (fun c -> Printf.printf "%d " (Char.code c)) "AB";
print_newline ();
Printf.printf "%s %s\n" (string_of_int 42) (string_of_float 2.5);
Printf.printf "%d %.1f\n" (int_of_string "17") (float_of_string "3.5");
Printf.printf "%5d|%-5d|%05d|%x|%e\n" 42 42 42 255 12345.678Ausgabe:
11 HALLO OCAML hallo ocaml
H OCaml
true true
a-b-c
Hallo
OCaml
[x]
H4llo OC4ml
6
***
65 66
42 2.5
17 3.5
42|42 |00042|ff|1.234568e+04Eigene Module
Ein module bündelt Typen und Funktionen; eine sig legt die öffentliche Schnittstelle fest:
module type STAPEL = sig
type 'a t
val leer : 'a t
val push : 'a -> 'a t -> 'a t
val pop : 'a t -> ('a * 'a t) option
val groesse : 'a t -> int
end
module Stapel : STAPEL = struct
type 'a t = 'a list
let leer = []
let push x s = x :: s
let pop = function [] -> None | x :: r -> Some (x, r)
let groesse = List.length
end
let () =
let s = Stapel.(leer |> push 1 |> push 2 |> push 3) in
Printf.printf "%d\n" (Stapel.groesse s);
match Stapel.pop s with
| Some (oben, _) -> Printf.printf "oben: %d\n" oben
| None -> print_endline "leer"Ausgabe:
3
oben: 3Der Typ 'a t ist nach außen abstrakt: Aufrufer können nicht wissen, dass es eine Liste ist.
Hashtbl, Map und Set
module SMap = Map.Make (String)
module ISet = Set.Make (Int)
let () =
let h = Hashtbl.create 16 in
Hashtbl.add h "eins" 1;
Hashtbl.replace h "zwei" 2;
Hashtbl.replace h "zwei" 22;
Printf.printf "%d %d %b\n" (Hashtbl.find h "eins") (Hashtbl.find h "zwei") (Hashtbl.mem h "drei");
Printf.printf "%d\n" (Hashtbl.length h);
(* unveränderliche Map *)
let m = SMap.(empty |> add "b" 2 |> add "a" 1 |> add "c" 3) in
SMap.iter (fun k v -> Printf.printf "%s=%d " k v) m;
print_newline ();
Printf.printf "%d %b\n" (SMap.find "b" m) (SMap.mem "z" m);
(match SMap.find_opt "z" m with Some v -> Printf.printf "%d\n" v | None -> print_endline "kein z");
let s = ISet.of_list [3; 1; 2; 3; 1] in
Printf.printf "%d %b\n" (ISet.cardinal s) (ISet.mem 2 s);
ISet.iter (Printf.printf "%d ") (ISet.union s (ISet.of_list [9]));
print_newline ()Ausgabe:
1 22 false
2
a=1 b=2 c=3
2 false
kein z
3 true
1 2 3 9Arrays
Arrays sind veränderlich und haben wahlfreien Zugriff:
let () =
let a = [| 5; 3; 9; 1 |] in
a.(0) <- 50;
Printf.printf "%d %d\n" a.(0) (Array.length a);
Array.sort compare a;
Array.iter (Printf.printf "%d ") a;
print_newline ();
let q = Array.map (fun x -> x * x) a in
Array.iter (Printf.printf "%d ") q;
print_newline ();
Printf.printf "%d\n" (Array.fold_left (+) 0 a);
let m = Array.make_matrix 2 3 0 in
m.(1).(2) <- 7;
Array.iter (fun z -> Array.iter (Printf.printf "%d ") z; print_newline ()) m;
Array.iteri (fun i x -> Printf.printf "%d:%d " i x) (Array.init 3 (fun i -> i * 10));
print_newline ()Ausgabe:
50 4
1 3 9 50
1 9 81 2500
63
0 0 0
0 0 7
0:0 1:10 2:20Funktionen höherer Ordnung und Pipelines
let () =
let ergebnis =
[1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
|> List.filter (fun x -> x mod 2 = 0)
|> List.map (fun x -> x * x)
|> List.fold_left (+) 0
in
Printf.printf "%d\n" ergebnis;
let komposition f g x = g (f x) in
let f = komposition (fun x -> x + 1) (fun x -> x * 10) in
Printf.printf "%d\n" (f 4);
let ( |+> ) x f = f x in
Printf.printf "%d\n" (3 |+> (fun x -> x + 1))Ausgabe:
220
50
4Merke
String,List,Array,Hashtbl,MapundSetsind Standardmodulemodule/sigkapseln Implementierungen hinter Schnittstellen- Der Pipe-Operator
|>macht Datenflüsse lesbar - Arrays und Hashtbl sind veränderlich, List/Map/Set nicht
Übungsaufgabe
Zähle mit einer Hashtbl die Häufigkeit der Wörter in einem Satz.
Quiz zur Selbstkontrolle
Was bewirkt eine Modul-Signatur (sig)?
- Sie legt die öffentliche Schnittstelle fest (richtig)
- Sie startet das Programm
- Sie kompiliert den Code
- Sie importiert Dateien
Was ist an Map in OCaml besonders?
- Sie ist unveränderlich (persistent) (richtig)
- Sie ist immer sortiert
- Sie ist nur für Strings
- Sie ist langsam
Was macht |>?
- Gibt den linken Wert an die rechte Funktion weiter (richtig)
- Vergleicht zwei Werte
- Verkettet Strings
- Beendet ein Programm
Weiter im Kurs
Zurück: Varianten und algebraische Datentypen
Weiter: Funktional vertieft: Lazy, GADTs und Objekte
Alle Kapitel: OCaml im Überblick