Listen
Listen sind unveränderliche, einfach verkettete Folgen gleichartiger Elemente:
let () =
let z = [5; 3; 9; 1; 7] in
let zeige l = print_endline ("[" ^ String.concat "; " (List.map string_of_int l) ^ "]") in
zeige z;
zeige (0 :: z);
zeige (z @ [8; 9]);
zeige (List.rev z);
zeige (List.sort compare z);
zeige (List.map (fun x -> x * 2) z);
zeige (List.filter (fun x -> x > 4) z);
Printf.printf "%d %d\n" (List.length z) (List.hd z);
Printf.printf "%d\n" (List.fold_left (+) 0 z);
Printf.printf "%b %b\n" (List.mem 9 z) (List.exists (fun x -> x > 8) z);
Printf.printf "%b\n" (List.for_all (fun x -> x > 0) z);
zeige (List.init 5 (fun i -> i * i));
zeige (List.concat [[1; 2]; [3]; [4; 5]]);
List.iteri (fun i x -> Printf.printf "%d:%d " i x) [10; 20; 30];
print_newline ();
let (gerade, ungerade) = List.partition (fun x -> x mod 2 = 0) [1; 2; 3; 4; 5; 6] in
zeige gerade; zeige ungerade;
let paare = List.combine [1; 2; 3] ["a"; "b"; "c"] in
List.iter (fun (n, s) -> Printf.printf "%d%s " n s) paare;
print_newline ()[5; 3; 9; 1; 7] [0; 5; 3; 9; 1; 7] [5; 3; 9; 1; 7; 8; 9] [7; 1; 9; 3; 5] [1; 3; 5; 7; 9] [10; 6; 18; 2; 14] [5; 9; 7] 5 5 25 true true true [0; 1; 4; 9; 16] [1; 2; 3; 4; 5] 0:10 1:20 2:30 [2; 4; 6] [1; 3; 5] 1a 2b 3c
Listen rekursiv verarbeiten
let rec summe = function
| [] -> 0
| kopf :: rest -> kopf + summe rest
let rec laenge = function
| [] -> 0
| _ :: rest -> 1 + laenge rest
let rec map f = function
| [] -> []
| x :: rest -> f x :: map f rest
let rec nimm n l = match n, l with
| 0, _ | _, [] -> []
| n, x :: rest -> x :: nimm (n - 1) rest
let () =
Printf.printf "%d %d\n" (summe [1; 2; 3; 4]) (laenge ["a"; "b"; "c"]);
List.iter (Printf.printf "%d ") (map (fun x -> x * x) [1; 2; 3; 4]);
print_newline ();
List.iter (Printf.printf "%d ") (nimm 2 [10; 20; 30]);
print_newline ()10 3 1 4 9 16 10 20
Tupel
let min_max l =
List.fold_left (fun (lo, hi) x -> (min lo x, max hi x)) (max_int, min_int) l
let () =
let punkt = (3, 4) in
let (x, y) = punkt in
Printf.printf "%d %d %d %d\n" x y (fst punkt) (snd punkt);
let (lo, hi) = min_max [5; 2; 9; 4] in
Printf.printf "%d %d\n" lo hi;
let dreifach = ("Mia", 17, true) in
let (n, a, _) = dreifach in
Printf.printf "%s %d\n" n a3 4 3 4 2 9 Mia 17
Records
Records sind benannte Felder – wie Strukturen anderer Sprachen:
type person = { name : string; alter : int; mutable punkte : int }
let () =
let p = { name = "Mia"; alter = 17; punkte = 0 } in
Printf.printf "%s %d\n" p.name p.alter;
p.punkte <- p.punkte + 10;
Printf.printf "%d\n" p.punkte;
(* unveränderliche Kopie mit Änderung *)
let q = { p with alter = 18 } in
Printf.printf "%s %d %d\n" q.name q.alter q.punkte;
let { name; alter; _ } = q in
Printf.printf "%s ist %d\n" name alterMia 17 10 Mia 18 10 Mia ist 18
Option: fehlende Werte ohne null
let teile a b = if b = 0 then None else Some (a / b)
let () =
(match teile 10 2 with
| Some r -> Printf.printf "Ergebnis %d\n" r
| None -> print_endline "Division durch null");
(match teile 1 0 with
| Some r -> Printf.printf "Ergebnis %d\n" r
| None -> print_endline "Division durch null");
Printf.printf "%d\n" (Option.value (teile 8 4) ~default:(-1));
Printf.printf "%d\n" (Option.value (teile 8 0) ~default:(-1));
(match Option.map (fun x -> x + 1) (Some 4) with Some v -> Printf.printf "%d\n" v | None -> ());
(match List.find_opt (fun x -> x > 3) [1; 5; 9] with Some v -> Printf.printf "%d\n" v | None -> ())Ergebnis 5 Division durch null 2 -1 5 5
Merke
- Listen sind unveränderlich:
::(voranstellen),@(verketten),List.map/filter/fold_left - Rekursion über Listen mit
[]undkopf :: rest - Tupel bündeln unterschiedliche Werte; Records haben benannte Felder (
mutableoptional) option(Some/None) ersetzt null
Aufgabe
Schreibe umkehren (ohne List.rev) und teste sie mit einer Liste von Strings.