Unwrapped Polymorphic Variant in Function Declaration

I understand that I can use @external and @unwrap with polymorphic variants to call into JavaScript APIs that are informally polymorphic, as in the padLeft example provided in the documentation: Bind to JS Function | ReScript Language Manual. I’m wondering if I can go the other direction: write a rescript function which compiles to a JavaScript function that accepts an informal polymorphic variant?

I’m writing a library that is used primarily by TypeScript/JavaScript users. I’ve written much of the library internals in ReScript and I would like to port everything to ReScript, but the JS API leverages this informal polymorphism so I would need a way to produce that in ReScript.

Specifically, I’m looking to be able to write something like:

type poly = @unwrap [ #N(NodeRepr.t) | #C(float) ]

@genType
let svf = (~key: option<string>=?, ~mode: string="lowpass", fc: poly, xn: poly) => {
  switch key {
    | Some(k) => NodeRepr.create("svf", {"key": k, "mode": mode}, [fc, xn])
    | None => NodeRepr.create("svf", {"mode": mode}, [fc, xn])
  }
}

and have it compile to some TypeScript/JavaScript that my users can call that looks like this:

export const svf: (_1:{ readonly key?: string; readonly mode?: string }, _2:NodeRepr_t|number, _3:NodeRepr_t|number) => NodeRepr_t = function (Arg1: any, Arg2: any, Arg3: any, Arg4: any) {
  /* Some auto-generated javascript to wrap the informal arg2 and arg3 into a poly variant */
  const a2 = typeof Arg2 === 'number' ? { tag: 'C', val: a2} : { tag: 'N', val: a2 };
  const a3 = typeof Arg2 === 'number' ? { tag: 'C', val: a3} : { tag: 'N', val: a3 };
  const result = Curry._5(
  GeneratedBS.svf, Arg1.key, Arg1.mode, a2, a3);
  return result
};

Does that make sense? This way I can write in ReScript with formal polymorphic variants, but via @unwrap (or similar), ship an API to TS/JS users that they’re more familiar with.

See if the recently introduced untagged variant would help for this.

1 Like

Awesome, I hadn’t seen that announcement! This looks like it could be exactly what I’m looking for, I’ll have a go with it. Thanks.

1 Like