I’m working on interfacing with some heavily inheritance based JS, and was wondering if I could somehow model the following scenario (in TS for typing):
type Thing;
interface HasThing {
  thing: Thing;
}
interface Item extends HasThing {
  thing: Thing;
  foo: Foo
}
const doThing: (thing: HasThing) => do(thing.thing);
I feel like functors are maybe the right path? But then how:
- Can I “appened” the 
thing field to a ReScript record type?  Is it even possible? 
- Can I “use” the functor type in my function signature?
 
- Can I combine many functors together (as this isn’t the only field like this)?
 
Ideally I don’t have to list every permutation, as it has just enough permutations to be both tedious and doItemThing seems frustrating to write.
Otherwise, this language has been a total dream 
             
            
              
              
              1 Like
            
            
                
                
              
           
          
            
            
              It would look something like:
type thing
module type HasThing = {
  let thing: thing
}
module type Item = {
  include HasThing
  let foo: foo
}
// Functor approach
module DoThing = (Thing: HasThing) => {
  do(Thing.thing)
}
// First-class module approach
let doThing = (thing: (module HasThing)) => {
  let (module Thing) = thing
  do(Thing.thing)
}
You can go with either approach.
- The 
thing field is inside a module type, so it can’t be appended to a record type 
- Yes, see the first-class module approach above (you may need to tweak the syntax a bit, I’m not sure I got it totally right in ReScript syntax)
 
- If by ‘combine’ you mean the 
Thing functor argument can ‘inherit’ or ‘extend’ many interfaces, then yes you can, e.g. 
module DoThing = (Thing: {
  include HasThing
  include HasOtherThing
  include HasSomethingElse
}) => {
  do(Thing.thing)
}
Same for the first-class module approach.
             
            
              
              
              3 Likes