EMZETT.
Login

Kurz: Ein module bündelt Typen und Funktionen; eine sig legt die öffentliche Schnittstelle fest:

Teil des Kurses OCaml

Kapitel 5 von 8 im Kurs OCaml. Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

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.678

Ausgabe:

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, Map und Set sind Standardmodule
  • module/sig kapseln 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

Weiter im Kurs

Zurück: Varianten und algebraische Datentypen

Weiter: Funktional vertieft: Lazy, GADTs und Objekte

Alle Kapitel: OCaml im Überblick