Interface file syntax issue for a module passed in function argument

Hey everyone!

I have made this abstracted snippet of code, with the full code working as intended in my codebase, but now I would like to freeze the definitions with an interface file.

I’m encountering a syntax issue on the let query where naively I would write in my .resi :

interface file
    let query:
      type data variables. (
        module(Query.Operation with
          type t = data
          and type t_variables = variables
        ),
        request<variables> => unit,
      ) => query

Unfortunately, the syntax is broken with the usage of the keywords “with”, “type” or “and” in a .resi
I tried to generate the file with the inferred types with bsc -i but it wouldn’t generate or output anything.

Also it feels I’m missing some understanding with the module syntax and in my .res file I could eventually get rid of the type data variables. (...) part thanks to an interface file.

Thank you for helping, and have a great day :slight_smile:

Hi! Have you tried using the command that comes with rescript-vscode extension? For me it usually works more reliably than bsc -i.

1 Like

Thank you, I wasn’t aware of this command!
It does generate the file, unfortunately with a syntax error “Did you forget a ‘type’ here?” at line 3:

let query: (
  module(Query.Operation
    with t = 'data
    with t_variables = 'variables
  ),
  request<variables> => unit,
) => unit

I think the correct syntax is this:

module(Query.Operation with type t = 'data and type t_variables = 'variables)

Never used these advanced language features myself though, so not sure.

It’s strange that the extension command produced the incorrect code, I used to that with the CLI one, but extension have worked great so far for me.

Another tool that can be useful in such cases, BTW, is the rescript format that lets you convert from OCaml to ReScript:

$ echo "val test : (module Test with type t = int)" | npx rescript format -stdin .mli 

Outputs: let test: module(Test with type t = int)

2 Likes

Awesome! I tried but missed the “and” on second line :sweat_smile:
It fully works in the codebase.

Thank you

result
let query: (
  module(Query.Operation
    with type t = 'data
    and type t_variables = 'variables
  ),
  request<'variables> => unit,
) => unit

I wonder why these advanced usage keywords aren’t referenced at all in the documentation.

2 Likes

Because, I think that all users who never wrote intensive code in Ocaml / F# / Haskell gonna wonder: how can it help me, and why should I use it ?
Same question about GADT, I still don’t understand why should I use it.

There could be a disclaimer about advanced usages, as this is a language feature and not a concept like GADTs in ReScript.
But I found surprising the fact some keywords don’t even appear in the syntax-lookup page!

There’re plans to add the documentation judging by the issues:

With the universally quantified types and locally abstract types the situation probably is similar, although no issues yet.

1 Like