in F#, the following is a no brainer:
let l = [1;2;3;4]
let s = sprintf "%A" l
where "%A" prints a formatted version of virtually any common, even recursive data structure.
Is there something similarly easy in ocaml?
There is something close, the %a specificator accepts two arguments, the first is a pretty printer for type 'a, and the second is a value of type 'a. The type of the printer, depends on the kind of used printf function. For example,
open Core_kernel.Std
open Format
printf "%a" Int63.pp Int63.one
Of course, this depends heavily on a good support from a library. If there is no pp function, provided for the type, then it is pretty useless.
Also there is a custom_printf syntax extension available for both - pp and ppx. In this extension you place a module name in the place of specificator. The module must have a to_string function. The ppx version, requires an exclamation mark before the format string:
printf !"%{Int63}" Int63.one
There is also a dump function, available over the Internet. In particular you can find it in the Batteries library. It recurse over the data representation and print it in a more or less human readable representation. But this is not relate to the formatted output.
Related
I am using a 3rd party module which exposes a function:
val pp : Format.formatter -> 'a -> unit
Unfortunately it doesn't expose a to_string (or show) function.
I want to find a way to use the result of pp in a format string, something like:
let output = Format.sprintf "Result: %s" (SomeModule.pp fmt myval)
But pp writes to fmt and returns unit so of course this is not valid.
I can tell I need to somehow make a formatter to pass to pp that writes to a string buffer, that I can then get contents of as a string, which I can then pass as an arg to sprintf
The use of pp like functions for making types printable seems pretty ubiquitous in OCaml (e.g. ppx_deriving show generates them) so I feel like there should be a simple way to achieve this, but I'm currently missing it.
By using asprintf instead, it's possible to use the %a format specifier to pass two arguments, a printer function and the value to be printed, which will then be formatted accordingly and inserted in its place:
let output = Format.asprintf "Result: %a" SomeModule.pp myval
The reason asprintf has to be used instead of sprintf is that the latter specifies an "input source" (the second argument of the format type) of type unit, while the former uses a formatter. This is what's going to be passed to the printer.
It still alludes me why there's a need for sprintf though, rather than just having asprintf. Perhaps there's some performance-related reason for it, but my guess is that it's just an artifact of history.
I was desperately looking for the last hour for a method in the OCaml Library which converts an 'a to a string:
'a -> string
Is there something in the library which I just haven't found? Or do I have to do it different (writing everything by my own)?
It is not possible to write a printing function show of type 'a -> string in OCaml.
Indeed, types are erased after compilation in OCaml. (They are in fact erased after the typechecking which is one of the early phase of the compilation pipeline).
Consequently, a function of type 'a -> _ can either:
ignore its argument:
let f _ = "<something>"
peek at the memory representation of a value
let f x = if Obj.is_block x then "<block>" else "<immediate>"
Even peeking at the memory representation of a value has limited utility since many different types will share the same memory representation.
If you want to print a type, you need to create a printer for this type. You can either do this by hand using the Fmt library (or the Format module in the standard library)
type tree = Leaf of int | Node of { left:tree; right: tree }
let pp ppf tree = match tree with
| Leaf d -> Fmt.fp ppf "Leaf %d" d
| Node n -> Fmt.fp ppf "Node { left:%a; right:%a}" pp n.left pp n.right
or by using a ppx (a small preprocessing extension for OCaml) like https://github.com/ocaml-ppx/ppx_deriving.
type tree = Leaf of int | Node of { left:tree; right: tree } [##deriving show]
If you just want a quick hacky solution, you can use dump from theBatteries library. It doesn't work for all cases, but it does work for primitives, lists, etc. It accesses the underlying raw memory representation, hence is able to overcome (to some extent) the difficulties mentioned in the other answers.
You can use it like this (after installing it via opam install batteries):
# #require "batteries";;
# Batteries.dump 1;;
- : string = "1"
# Batteries.dump 1.2;;
- : string = "1.2"
# Batteries.dump [1;2;3];;
- : string = "[1; 2; 3]"
If you want a more "proper" solution, use ppx_deriving as recommended by #octachron. It is much more reliable/maintainable/customizable.
What you are looking for is a meaningful function of type 'a. 'a -> string, with parametric polymorphism (i.e. a single function that can operate the same for all possible types 'a, even those that didn’t exist when the function was created). This is not possible in OCaml. Here are explications depending on your programming background.
Coming from Haskell
If you were expecting such a function because you are familiar with the Haskell function show, then notice that its type is actually show :: Show a => a -> String. It uses an instance of the typeclass Show a, which is implicitly inserted by the compiler at call sites. This is not parametric polymorphism, this is ad-hoc polymorphism (show is overloaded, if you want). There is no such feature in OCaml (yet? there are projects for the future of the language, look for “modular implicits” or “modular explicits”).
Coming from OOP
If you were expecting such a function because you are familiar with OO languages in which every value is an object with a method toString, then this is not the case of OCaml. OCaml does not use the object model pervasively, and run-time representation of OCaml values retains no (or very few) notion of type. I refer you to #octachron’s answer.
Again, toString in OOP is not parametric polymorphism but overloading: there is not a single method toString which is defined for all possible types. Instead there are multiple — possibly very different — implementations of a method of the same name. In some OO languages, programmers try to follow the discipline of implementing a method by that name for every class they define, but it is only a coding practice. One could very well create objects that do not have such a method.
[ Actually, the notions involved in both worlds are pretty similar: Haskell requires an instance of a typeclass Show a providing a function show; OOP requires an object of a class Stringifiable (for instance) providing a method toString. Or, of course, an instance/object of a descendent typeclass/class. ]
Another possibility is to use https://github.com/ocaml-ppx/ppx_deriving with will create the function of Path.To.My.Super.Type.t -> string you can then use with your value. However you still need to track the path of the type by hand but it is better than nothing.
Another project provide feature similar to Batterie https://github.com/reasonml/reason-native/blob/master/src/console/README.md (I haven't tested Batterie so can't give opinion) They have the same limitation: they introspect the runtime encoding so can't get something really useable. I think it was done with windows/browser in mind so if cross plat is required I will test this one before (unless batterie is already pulled). and even if the code source is in reason you can use with same API in OCaml.
I have defined a big pretty printer pp: out_channel -> t -> unit over a big type t. Therefore, I can use it like Printf.fprintf stdout "%a" x where x: t, or chain printing like Printf.fprintf chan "%a" pp x where chan: out_channel.
Now I need to convert what is printed to a string or a text. Does anyone know if there is a way to leverage/use the function pp rather than writing a function to_string: t -> unit from scratch?
Format.asprintf should suit your needs, if you pp is implemented for Format.formatter type instead of out_channel. The Format.formatter is a more general type and should be preferred to the concrete out_channel. In fact, a sort of a standard type for pretty printer is the Format.formatter -> 'a -> unit type, at least it is required by the #install_printer directive in OCaml toplevel, debugger and other facilities. Functions of the same type are used in Core library to implement Pretty_printer interface.
So, if you will reimplement your pp function to work with the Format module (usually for this it would be enough just to open Format module), then you can reuse it. The functions, that print to out_channel module can't be retargetered to print into string. So it is better not to write them.
To make this work you need something that looks to OCaml like an out channel, but keeps the data in a string (or buffer) instead. There's nothing like this in OCaml, unfortunately.
An OCaml module usually contains at least one abstract type whose idiomatic name is t. Also, there's usually a function that constructs a value of that type.
What is the usual / idiomatic name for this?
The StdLib is not consistent here. For example:
There's Array.make and a deprecated function Array.create. So that function should be named make?
On the other hand, there's Buffer.create but not Buffer.make. So that function should be named create?
Some people find this way of module design makes OCaml programming easier, but this is not a mandatory OCaml programming style, and I do not think there is no official name for it. I personally call it "1-data-type-per-1-module" style. (I wrote a blog post about this but it is in Japanese. I hope some autotranslator gives some useful information to you ...)
Defining a module dedicated to one data type and fix the name of the type t has some values:
Nice namespacing
Module names explain about what its type and values are, therefore you do not need to repeat type names inside: Buffer.add_string instead of add_string_to_buffer, and Buffer.create instead of create_buffer. You can also avoid typing the same module names with local module open:
let f () =
let open Buffer in
let b = create 10 in (* instead of Buffer.create *)
add_string b "hello"; (* instead of Buffer.add_string *)
contents b (* instead of Buffer.contents *)
Easy ML functor application
If an ML functor takes an argument module with a data type, we have a convention that the type should be called t. Modules with data type t are easily applied to these functors without renaming of the type.
For Array.create and Array.make, I think this is to follow the distinction of String.create and String.make.
String.create is to create a string with uninitialized contents. The created string contains random bytes.
String.make is to create a string filled with the given char.
We had Array.create for long, to create an array whose contents are filled with the given value. This behavior corresponds with String.make rather than String.create. That's why it is now renamed to Array.make, and Array.create is obsolete.
We cannot have Array.create in OCaml with the same behaviour of String.create. Unlike strings, arrays cannot be created without initialization, since random bytes may not represent a valid OCaml value for the content in general, which leads to a program crash.
Following this, personally I use X.create for a function to create an X.t which does not require an initial value to fill it. I use X.make if it needs something to fill.
I had the same question when I picked up the language a long time ago. I never use make and I think few people do.
Nowadays I use create for heavy, often imperative or stateful values, e.g. a Unicode text segmenter. And I use v for, functional, lighter values in DSL/combinator based settings, e.g. the various constructors in Gg, for example for 2D vectors, or colors.
As camlspotter mentions in his answer the standard library distinguishes make and create for values that need an initial value to fill in. I think it's better to be regular here and always use create regardless. If your values support an optional initial fill value, add an optional argument to create rather than multiply the API entry points.
How to print the internal OCaml representation of a term in Coq (exposing the data constructors like Lambda, App, Rel, etc... )?
Is there any equivalent of derived show, as in Haskell, in OCaml?
You can print the body of any Coq term using the vernacular command Show. There is a lot of notations in Coq that can hide some terms, so you can also deactivate the notations using CoqIDE's menu, or using the command Set Printing All. in coqtop/ProofGeneral, prior to calling Show.
However this will expose the term in the Coq language, not it's OCaml encoding. If you want the underlying Ocaml representation, I guess you'll have to hack a bit Coq's code. I am not aware of any such command as for today.
For the show type class, I don't think there is one in the std, by I might mistaken.