The OCaml standard library provides many convertion functions of the form
Foo.{to,of}_bar
between its various types. These are incomplete – and somewhat
arbitrary – so it's often necessary to go via intermediate types to achieve the
convertion you want. (Either that or roll your own with a fold
or iter
function.)
What's worse, you may need to mix forwards and backwards conversions (to_
and
of_
style respectively), requiring you to search both forwards and backwards
in the documentation to get the conversion you need. For example, consider the
case of ('k, 'v) Hashtbl.t -> ('k * 'v) list
:
-
Looking in the docs for
Hashtbl
, we see that there's no direct conversion to an association list. We might give up and build our own one withHashtbl.fold
. On OCaml 4.07+, we haveHashtbl.to_seq : ('k, 'v) Hashtbl.t -> ('k, 'v) Seq.t
, so let's start by using that. -
We look in the docs for
Seq
, and find no conversions. Once again, we could use get distracted and useSeq.fold_left
to build our own. Or, we could start searching backwards from the type we want... -
In the docs for
List
, we find the functionList.of_seq : 'a Seq.t -> 'a List.t
. Now we can complete the chain:
let hashtbl_to_list h = Hashtbl.to_seq h |> List.of_seq
Rather than keeping the entire Stdlib documentation open in browser tabs, it can be helpful to view all of the available conversions as a directed graph. That's what this repository provides. (These graphs show the conversions available on OCaml 4.11.0; your mileage may vary.)
Take-aways:
-
The common containers are ordered by:
Array
⊏List
⊏Seq
Buffer
⊏Bytes
⊏String
⊏Seq
- {
Hashtbl
,Map
,Queue
,Set
,Stack
} ⊏Seq
-
To convert between containers
Foo.t
→Bar.t
, it's usually necessary to go viaSeq.t
withFoo.to_seq >> Bar.of_seq
. -
There's no direct conversion between
float Array.t
andFloat.Array.t
.
Take-aways:
- The numeric modules are ordered by
Int64
⊏Nativeint
⊏Int32
⊏ {Int
,Float
}. When coercing between them, you should check modules in this order.