Not all OCaml types are allowed.
There are a lot of tests that exercise the rules here.
For function arguments, you can use
t(i.e., the main type of the current module)
- Other module types (e.g.,
- Arrays of any of the above types
- Lists of any of the above types
- Seq.t of any of the above types
'a option array,
'a option list,
'a option Seq.t
Py.Object.tif you need to deal with
- Certain kinds of tuples
Note that your custom types must be newly minted modules. E.g.,
(* This is okay *) module Doc = struct type t let of_pyobject ... let to_pyobject ... ... end (* But this is not *) type doc let doc_of_pyobject ... let doc_to_pyobject ...
For return types, you can use all of the above types plus
'a Or_error.t for types
'a other than
unit. However, you cannot use
unit list, or
You can also return many kinds of tuples directly. See here.
Note: currently, you're not allowed to have nested
Or_error.t. If you need them, you will have to bind those functions by hand :)
'a array list will fail.
You are allowed to nest
'a option in arrays, lists, and
'a option list); however, this will not work with
Sometimes you may want to deal directly with
Maybe you have a Python function that is truly polymorphic, or you just don't feel like giving a function a specific OCaml type for whatever reason. Regardless, you can use
Py.Object.t for this.
Of course, you will be leaking a bit of the
pyml implementation into your API, but sometimes that is unavoidable, or just more convenient than dealing with it in another way.
Note that you currently are not allowed to nest
pytypes in any of the containers or monads.
You can handle many kinds of tuples directly. See here.
Alternatively, you could mark them as
Py.Object.t and let the caller deal with them in some way.
There are two placeholders you can use:
If you're binding a large library and you aren't planning on implementing a function, but you want it in the signature for whatever reason, you can use
not_implemented. If you are planning to come back and implement a function later, you can use
val f : 'a todo val g : 'a not_implemented
These are special in that you can't just use them anywhere, it has to be exactly as above.
The generated functions for the above signatures will be like this:
let f () = failwith "todo: f" let g () = failwith "not implemented: g"
So if a user actually calls these functions, the program will fail at runtime.