module type Symantics = sig type 'a repr val int : int -> int repr val add : int repr -> int repr -> int repr val mul : int repr -> int repr -> int repr val app : ('a -> 'b) repr -> 'a repr -> 'b repr val lam : ('a repr -> 'b repr) -> ('a -> 'b) repr end ;; module Test(S:Symantics) = struct let test1 () = S.add (S.int 1) (S.int 2) let test2 () = S.mul (test1 ()) (S.int 2) let test3 () = S.lam (fun x -> S.add x (S.int 2)) let test4 () = S.app (test3 ()) (test2 ()) end ;; module Interp = struct type 'a repr = 'a let int i = i let add x y = x + y let mul x y = x * y let app f x = f x let lam f = f end ;; module Length = struct type 'a repr = int let int _ = 1 let add x y = x + y let mul x y = x + y let app f x = f + x let lam f = f 0 + 1 end ;; module T = Test(Interp);; T.test1 ();; T.test2 ();; T.test3 ();; T.test4 ();; module T2 = Test(Length);; T2.test1 ();; T2.test2 ();; T2.test3 ();; T2.test4 ();;