let prelude = import! std.prelude let { (<|) } = import! std.function let { run, Test, assert_eq, test, group, ? } = import! std.test let { (*>), ? } = import! std.applicative let { ? } = import! std.effect let ints input = match input with | 0 -> 1 | 1 -> 2 | _ -> 3 let strings input = match input with | "A" -> 4 | "B" -> 5 | _ -> 6 type N = | A Int | B let ns input = match input with | A 1 -> 7 | A 2 -> 8 | B -> 9 | _ -> 10 type R1 = { x: Int } let r1 input = match input with | { x = 2 } -> 11 | { x = 3 } -> 12 | _ -> 13 type R2 = { x: Int, y: Int } let r2 input = match input with | { x = 2, y = 3 } -> 14 | { x = 3, y = 4 } -> 15 | _ -> 16 type TestM = | TestM Int String let test_m input = match input with | TestM 1 "hello" -> 20 | TestM _ "world" -> 21 | TestM 2 _ -> 22 | _ -> 23 let match_ns = assert_eq (ns (A 1)) 7 *> assert_eq (ns (A 2)) 8 *> assert_eq (ns B) 9 *> assert_eq (ns (A 3)) 10 let match_ints = assert_eq (ints 0) 1 *> assert_eq (ints 1) 2 *> assert_eq (ints 2) 3 *> assert_eq (ints 3) 3 let match_strings = assert_eq (strings "A") 4 *> assert_eq (strings "B") 5 *> assert_eq (strings "") 6 let match_r1 = assert_eq (r1 { x = 2 }) 11 *> assert_eq (r1 { x = 3 }) 12 *> assert_eq (r1 { x = 4 }) 13 let match_r2 = assert_eq (r2 { x = 2, y = 3 }) 14 *> assert_eq (r2 { x = 3, y = 4 }) 15 *> assert_eq (r2 { x = 4, y = 4 }) 16 let match_test_m = assert_eq (test_m (TestM 1 "hello")) 20 *> assert_eq (test_m (TestM 2 "world")) 21 *> assert_eq (test_m (TestM 2 "hello")) 22 *> assert_eq (test_m (TestM 3 "")) 23 group "match_literal" [test "match_ints" <| \_ -> match_ints, test "match_strings" <| \_ -> match_strings, test "match_ns" <| \_ -> match_ns, test "match_r1" <| \_ -> match_r1, test "match_r2" <| \_ -> match_r2, test "match_test_m" <| \_ -> match_test_m]