(* TEST flags = "-dshape"; expect; *) (* We depart slightly from the example in the PLDI'19 paper, which actually doesn't type... *) module type Stringable = sig type t val to_string : t -> string end [%%expect{| { "Stringable"[module type] -> <.2>; } module type Stringable = sig type t val to_string : t -> string end |}] module Pair (X : Stringable) (Y : Stringable) = struct type t = X.t * Y.t let to_string (x, y) = X.to_string x ^ " " ^ Y.to_string y end [%%expect{| { "Pair"[module] -> Abs<.9>(X, Y, { "t"[type] -> <.5>; "to_string"[value] -> <.6>; }); } module Pair : (X : Stringable) (Y : Stringable) -> sig type t = X.t * Y.t val to_string : X.t * Y.t -> string end |}] module Int = struct type t = int let to_string i = string_of_int i end [%%expect{| { "Int"[module] -> {<.13> "t"[type] -> <.10>; "to_string"[value] -> <.11>; }; } module Int : sig type t = int val to_string : int -> string end |}] module String = struct type t = string let to_string s = s end [%%expect{| { "String"[module] -> {<.17> "t"[type] -> <.14>; "to_string"[value] -> <.15>; }; } module String : sig type t = string val to_string : 'a -> 'a end |}] module P = Pair(Int)(Pair(String)(Int)) [%%expect{| { "P"[module] -> {<.18> "t"[type] -> <.5>; "to_string"[value] -> <.6>; }; } module P : sig type t = Int.t * Pair(String)(Int).t val to_string : Int.t * Pair(String)(Int).t -> string end |}];; P.to_string (0, ("!=", 1)) [%%expect{| {} - : string = "0 != 1" |}]