Let's say I have a user defined type like type foo = string * string list
, if I want to insert print debug statements in my code to see what values it holds, what would be the fastest way to do it?
Seems like writing
let (first, second) = foo in
printf "%s, %s" first (String.concat second)
is a way too much work for a quick and dirty debug statement!
One option is to use ppx_sexp_conv
. If you're using Core
, you don't have to do anything special. Loading core
gives you all you need. Just add [@@deriving sexp]
to all of your type definitions. For example:
# type foo = string * string list [@@deriving sexp];;
type foo = string * string list
val foo_of_sexp : Sexp.t -> foo = <fun>
val sexp_of_foo : foo -> Sexp.t = <fun>
# let foo = "hello", ["how"; "are"; "you"];;
val foo : string * string list = ("hello", ["how"; "are"; "you"])
# sexp_of_foo foo |> Sexp.to_string_hum;;
- : string = "(hello (how are you))"
It is also possible to generate the sexp function on the fly for types that weren't pre-defined. For example:
# [%sexp_of: string * int];;
- : string * int -> Sexp.t = <fun>
# [%sexp_of: string * int] ("foo", 42);;
- : Sexp.t = (foo 42)
You can try the BatPervasives.dump
function in the "OCaml Batteries Included" library. Install with opam install batteries
, then:
open Batteries
type 'a tree = Leaf | Node of 'a * 'a tree * 'a tree
let t1 = Node(1, Leaf, Leaf)
let t2 = Node(2, t1, Leaf)
let t3 = Node(3, Leaf, t2)
let () = print_endline (dump t3)
Build with:
ocamlfind ocamlc -package batteries -linkpkg testdump.ml
or:
ocamlbuild -pkg batteries testdump.byte
Running it should produce:
(3, 0, (2, (1, 0, 0), 0))
As you can see, it's a somewhat stripped down representation compared to REPL output (it relies on the Obj
module), but if you know the type, it's generally easy to figure out the value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With