Non top-level polymorphic type (aka 'a. notation)

Hello there !

For my FRP library, I need to have a function that create a truly polymorphic function (the proxy wrapper).

But the problem is that the created functions are monomorphic and cannot be reused on different types (as they should) to share the observing context.

let tilia: unit => 'a => 'a = () => {
   // setup context
   proxify(context, ...)
}

// Usage
let connect = tilia()

let a = connect({ firstname: "Ada", lastName: "Byron" }) // Ok, a now looks like a regular "person"

let b = connect({ title: "About math and foly" }) // Not ok: This record expression is expected to have type person

This is really a show-stopper for the ā€œforestā€ feature where you can create trees that share observing state…

Are there any solutions to this problem ? Has anyone had the same need and how was it solved ?

Thank you

PS: I found this solution but I would prefer to have a polymorphic function if possible…

type person = {name: string}
type article = {title: string}

// explicit context solution
let root = tilia()
// top-level function to avoid scoped polymorphism problem
let user = connect(root, {name: "Alice"})
let post = connect(root, {title: "Hello"})

There’s a certain trick to having higher-rank polymorphic functions, as detailed in this thread.

For your example, you might have to do some extra JS wrapping (or just tweak the implementation) of that proxify function, but it should be doable; see this playground link.

2 Likes

Thank you @cwstra :blush:

I learned something interesting here.

So what feels more natural ?

// explicit context object
connect(root, {name: "Alice"})

Or

// B (cwstra idea)
connect.f({name: "Alice"})
1 Like