Pretty Printing a Map

Hello,
When I introduced the Stdlib’s Map I didn’t have the means to print using [[@@deriving_show]
One of the other threads here mentioned Containers. So I switched to CCMap like this.

But still I couldn’t figure out how to print the entire value.
Some part of it is using [@@deriving_show]]. Map seems to be the only structure in this code that may necessitate a custom printer.

I need that because my test is like this. And without the map there is no problem with the printing mode.


let%expect_test _=

  Printf.printf "%s"  (fib (BInt 5)); (* This should Printf.printf*)
  [%expect {| (Lit 8) |}]
type expr =
    | Var of var_name
    | Abs of  var_name *  expr
    | App of expr *  expr
    | Lit of btype
    | Builtin of builtin_fn
    | Cond of expr *  expr *  expr
[@@deriving show]

module PPMap = struct
  module M = CCMap.Make(EnvKey)
  include M

  let pp = M.pp
end


  type value =
    | VInt of int
    | Closure of closure
  and closure = {env : env ; var : string ; body : expr} (* Edited to add string *)
  and
  env =
     EnvMap of value PPMap.M.t

Thanks,
Mohan

I’m not sure to understand exactly what you want to do. But if this is pretty-printing a map using Containers, this shows how you may proceed for a map from ints to strings (this could be improved by using fprintf and taking the key and value printers as arguments too, but I think it’s better to see the simpler way first):

module PPMAP = CCMap.Make(Int)

let print_map map = 
  Format.printf "@[<hov2>[%a@]]@." (PPMAP.pp CCInt.pp CCString.pp) map

let test = PPMAP.of_list [(3,"foo"); (1, "bar")]

 print_map test;;
[1 -> "bar", 3 -> "foo"]

1 Like

The solution works if I print it separately.
After asking I understand that

  1. [@@deriving_show] cannot be used with CCMap.
  2. PPMap.M.pp is not implemented if I use Map. So I may be able to provide it but it looks like I need to extend Map ?

module PPMap = struct
  module M = Map.Make(EnvKey)
  let pp ppf m =
   M.iter (fun k v -> Format.fprintf ppf "%s -> %s@\n" k v) m (* Sample *)
end


  type value =
    | VInt of int
    | Closure of closure
[@@deriving show]

  and closure = {env : env ; var : var_name ; body : expr}
[@@deriving show]
  and
  env =
     EnvMap of value PPMap.M.t

[@@deriving show]

Did I understand it ? The value should be printed as a whole.

Thanks

I don’t use deriving much but I think this should work:

module PPMap = CCMap.Make (Int)

type value = VInt of int
and closure = { env : env; var : string; body : value }

and env =
  | EnvMap of value PPMap.t
      [@printer
        fun fmt map -> fprintf fmt "%a" (PPMap.pp CCInt.pp pp_value) map]
[@@deriving show] (* only one call to `deriving show` is enough *)

(next time, please provide a MWE (minimal working example) when asking such a question, that is as small and simple as possible and without undefined notions, such as var_name)

I will avoid the confusion I created by not revealing the types properly.

And the code that works is this.

let%expect_test _=

  Printf.printf "%s" (Format.asprintf "%a" pp_value (fib (BInt 5)));
  [%expect {| |}]

module PPMap =CCMap.Make(EnvKey)


  type value =
    | VInt of int
    | Closure of closure
  and closure = {env : env ; var : string ; body : expr}
  and
  env =
  | EnvMap of value PPMap.t
      [@printer
        fun fmt map -> fprintf fmt "%a" (PPMap.pp CCString.pp pp_value) map]
[@@deriving show] (* only one call to `deriving show` is enough *)


Thanks. I understood how the functions PPMap.pp CCString.pp pp_value are available to use.