Calling convert_inline
in this context means that the return type of convert_inline
must always be compatible with the required type of b
. Consequently, the type of convert_inline
can be at most Html_types.b_contents_fun
as indicated by the return type:
[< Html_types.b_content_fun > ...
To avoid this issue, one must annotate the type of the group of mutually recursive functions.
Generally, with recursive functions on polymorphic variants, such annotations are useful to avoid error snowballing into complex error messages. Here, such annotations are required because the definitions are polymorphically recursive: the constraint on the type of the result of convert_inline
in the body of convert_inline
should not be applied to the convert_inline
function in general.
let rec convert_inline : 'a. Inline.t -> ( `[> Html_types.txt | `Br | `Code | `PCDATA ] as 'a) elt = function
| Emphasis _ -> txt "nope" (* convert_emphasis e *)
| Break_Line -> br ()
| Hard_Break_Line -> br ()
| Verbatim _ -> txt "nyi verbatim"
| Code s -> code [txt s]
| Tag _ -> txt "nyi tag"
| Spaces _ -> txt "nyi spaces"
| Plain s -> txt s
| Link link -> convert_link link
| Nested_link _ -> txt "nyi link"
| Target _ -> txt "nyi target"
| Subscript _ -> txt "nyi subscript"
| Superscript _ -> txt "nyi subscript"
| Footnote_Reference _ -> txt "nyi footnote"
| Cookie _ -> txt "nyi cookie"
| Latex_Fragment _ -> txt "nyi latext fragement"
| Macro _ -> txt "nyi macro"
| Entity _ -> txt "nyi entity"
| Timestamp _ -> txt "nyi timestamp"
| Radio_Target _ -> txt "nyi radio target"
| Export_Snippet (_, _) -> txt "nyi snippet"
| Inline_Source_Block _ -> txt "nyi inline"
| Email _ -> txt "nyi email"
| Inline_Hiccup _ -> txt "nyi hiccup"
| Inline_Html _ -> txt "nyi inline html"
and convert_emphasis : 'a. Inline.emphasis -> ([> Html_types.b | Html_types.txt] as 'a) elt =
fun (s,l) ->
match s with
| `Bold -> b (List.map ~f:convert_inline l)
| _ -> txt "nyi emphasis"