(* TEST * expect *) type _ constant = | Int: int -> int constant | Bool: bool -> bool constant type (_, _, _) binop = | Eq: ('a, 'a, bool) binop | Leq: ('a, 'a, bool) binop | Add: (int, int, int) binop let eval (type a) (type b) (type c) (bop:(a,b,c) binop) (x:a constant) (y:b constant) : c constant = match bop, x, y with | Eq, Bool x, Bool y -> Bool (if x then y else not y) | Leq, Int x, Int y -> Bool (x <= y) | Leq, Bool x, Bool y -> Bool (x <= y) | Add, Int x, Int y -> Int (x + y) let _ = eval Eq (Int 2) (Int 3) [%%expect{| type _ constant = Int : int -> int constant | Bool : bool -> bool constant type (_, _, _) binop = Eq : ('a, 'a, bool) binop | Leq : ('a, 'a, bool) binop | Add : (int, int, int) binop Lines 12-16, characters 2-36: 12 | ..match bop, x, y with 13 | | Eq, Bool x, Bool y -> Bool (if x then y else not y) 14 | | Leq, Int x, Int y -> Bool (x <= y) 15 | | Leq, Bool x, Bool y -> Bool (x <= y) 16 | | Add, Int x, Int y -> Int (x + y) Warning 8 [partial-match]: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (Eq, Int _, _) val eval : ('a, 'b, 'c) binop -> 'a constant -> 'b constant -> 'c constant = Exception: Match_failure ("", 12, 2). |}];;