External function taking external function as an argument

Hi

I have a js/ts api which looks sth like

// test.ts
export const f1 = () => {
    console.log("f1");
};

type fn = () => void;

export const f2 = (fn: fn) => {
   fn();
};

The bindings for it on the rescript side looks like

// usage.res
@module("./test") external f1: unit => unit = "f1"

type fnType = unit => unit
@module("./test") external f2: fnType => unit = "f2"

The usage on rescript side

// usage.res
f2(f1)

The resulting js output is

// usage.bs.js
import * as Test from "./test";
function f1(prim) {
    Test.f1();
}

function f2(prim) {
    Test.f2(prim);
}

Test.f2(f1);

My question is why Test.f1 function is wrapped in another function, how to not wrap it. Any suggestion or pointers are helpful.

I am using
Rescript: 9.1.4

Thanks
Srikanth

You need to tell the compiler to explicity uncurry the fnType signature with the dot syntax.

type fnType = (. unit) => unit
// usage.res
@module("./test") external f1: fnType = "f1"
@module("./test") external f2: fnType => unit = "f2"

f2(f1)

you can do the same with f2:

type fnType = (. unit) => unit
// usage.res
@module("./test") external f1: fnType = "f1"
@module("./test") external f2: (. fnType) => unit = "f2"

f2(. f1)

Keep in mind that then you’d need to call it with the dot syntax as well.

See also uncurried function docs.

5 Likes