Search code examples
ocamlrescript

Conversion from ocaml to rescript "Did you forget a `=>` here?" syntax error


Trying to convert this OCaml code to Rescript

let emptyEventHandler = ((((fun _ev -> ())
  [@bs ]) : Web.Node.event_cb) : Web.Node.event_cb)

And that is what I have got after the conversion

let emptyEventHandler: Web.Node.event_cb = ((. _ev) => (): Web.Node.event_cb)

the error is Did you forget a `=>` here? (at the end)

Does anyone know if this is caused by the syntax changes they made on Rescript and any idea on how can this be fixed?


Solution

  • The original OCaml has a duplicate type annotation for some reason. This is valid in OCaml because everything is an expression, and every expression can have a type annotation, but is completely redundant. One possible reason for this happening is that the code might have been converted between OCaml and Reason too many times.

    Rescript doesn't seem to support this case. It prefers type annotations on bindings and doesn't seem to support type annotations on expressions in general. But since Rescript is still represented by OCaml's AST, which does not make this distinction, it seems it will only take the first type annotation of a binding expression leaving the rest as-is and producing invalid Rescript code.

    I'd consider this a bug since I think it should produce an error instead of invalid code, but either way the fix is simple, just remove the extraneous type annotation.

    In OCaml it would then become:

    let emptyEventHandler = (((fun _ev -> ()) [@bs]) : Web.Node.event_cb)
    

    And in Rescript:

    let emptyEventHandler: Web.Node.event_cb = (. _ev) => ()