2021-02-15 11:14:52 +01:00

164 lines
3.7 KiB
OCaml

let () = print_endline "Pattern-matching:"
let () = print_string "simple: "
let () =
show_int (match [] with [] -> 2 | x :: l -> 3)
let () =
show_int (match 1 :: [] with
| [] -> 2 (* note: leading bar *)
| _ :: _ -> 3
)
let test_function = function
| [] -> 2
| x :: _ -> x + 1 (* note: one of the pattern arguments is a wildcard *)
let () =
show_int (test_function (3 :: []))
type 'a tree =
| Empty
| Leaf of 'a
| Node of 'a tree * 'a tree
let () =
show_int (match Node (Leaf 1, Leaf 2) with
| Empty -> 4
| Leaf _ -> 4
| Node _ -> 5 (* note: a single wildcard for several arguments *)
)
let () = print_newline ()
let () = print_string "irrefutable patterns in let-bindings: "
let () = show_int (
let (a, b) = (2, 3) in b - a
)
let () = print_newline ()
let () = print_string "nested patterns: "
let test_nested_patterns =
match Node(Leaf 0, Node(Leaf 8, Node(Leaf 2, Empty))) with
| Empty -> 0
| Leaf _ -> 0
| Node(_, Empty) -> 0
| Node(Empty, Node _) -> 1
| Node(Node _, Node _) -> 1
| Node(Leaf 0, Node (_, Node (_, Node _))) -> 2
| Node(Leaf 0, Node (Leaf x, Node (Leaf y, Empty))) -> x - y
| Node(Leaf 0, Node (_, Empty)) -> 4
| Node (a, b) ->
(match Node (a, b) with
| Node (Empty, _) -> 0
| Node (_, Empty) -> 0
| Node (Leaf _, Leaf _) -> 1
| _ -> 2)
let () = show_int test_nested_patterns
let () = print_newline ()
let () = print_string "as-patterns: "
let () = show_int (match (2, 3) with
| (_ as a, _) as p ->
let (_, b) = p in
b - a
)
let () = print_newline ()
let () = print_string "or-patterns: "
(* toplevel ors, no parentheses *)
let () = show_int (match 1 with
| 0 | 1 | 2 -> 1 (* no parentheses *)
| 3 | 4 -> 2
| 5 | _ -> 3
)
(* toplevel ors, with parentheses *)
let () = show_int (match 3 with
| (0 | 1 | 2) -> 1
| (3 | 4) -> 2 (* parentheses *)
| 5 | _ -> 3
)
(* in-depth ors *)
let () = show_int (match (2, 3) with
| ((0 | 1), _) -> 1
| (2, (0 | 1)) -> 2
| (2, (2 | 3)) -> 3
| ((3 | 4), _) -> 4
| _ -> 5
)
(* oring constant and non-constant patterns *)
let () = show_int (match Node (Empty, Empty) with
| Empty | Leaf _ -> 0
| Node ((Empty | Leaf _), Node _) -> 1
| Node (_, (Empty | Leaf _)) -> 4
| Node (Node _, Node _) -> 12
)
let () = print_newline ()
let () = print_string "record patterns"
type ('a, 'b) t = { a : 'a; b : 'b }
let () = show_int (match { a = Empty; b = Leaf 1 } with
| { a = (Leaf _ | Node _) } -> 0
| { b = (Empty | Node _) } -> 2
| { a = Empty; b = Leaf n } -> n
)
let () = print_newline ()
let () = print_string "string patterns"
let f = function
| "foo" -> 42
| "barbar" -> 21
| _ -> 0
let () = show_int (f "foo")
let () = show_int (2 * f "barbar")
let () = show_int (42 + f "bar")
let () = print_newline ()
let () = print_string "when-guards"
let () = show_int (match Node (Leaf 2, Leaf 2) with
| Node _ when (show_int 1; false) -> 0
| Node (Leaf n, (Leaf _ | Empty)) when (show_int n; false) -> 0
| Node _ -> 3
| _ -> 4
)
let () = print_newline ()
let () = print_string "match with exception"
let f ~success:b =
if b then 17
else raise (Failure " 42")
let () = match f ~success:true with
| n -> show_int n
| exception (Failure s) -> print_string s
let () = match f ~success:false with
| n -> show_int n
| exception (Failure s) -> print_string s
let () = print_newline ()
let () = print_string "interval patterns"
let f c = show_int (match c with
| 'c' | 'W' | '6' -> 0
| 'a'..'z' -> 1
| 'A'..'Z' -> 2
| '0'..'9' -> 3
| _ -> 4)
let () = f 'c'; f 'W'; f '6'; f 'a'; f 'b'; f 'd'; f 'z'; f 'A'; f 'V'; f 'X'; f 'Z'; f '0'; f '5'; f '7'; f '9'; f '/'; f ':'; f '@'; f '['; f '`'; f '{'
let () = print_newline ()