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+04
Eigene 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: 3
Der 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 9
Arrays
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:20
Funktionen 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 4
Merke
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
Aufgabe
Zähle mit einer Hashtbl die Häufigkeit der Wörter in einem Satz.