Does Rescript Still support impl ? (Or, any feature like trait constraints)

I had a code in Rust. I wanted to code this in Rescript.
Does Rescript support impl ? or anything similar to this ?

trait Trait1 {
    fn method1(&self);
}

trait Trait2 {
    fn method2(&self);
}

struct MyStruct;

impl Trait1 for MyStruct {
    fn method1(&self) {
        println!("Method 1 called");
    }
}

impl Trait2 for MyStruct {
    fn method2(&self) {
        println!("Method 2 called");
    }
}

fn call_methods<T>(item: &T)
where
    T: Trait1 + Trait2,
{
    item.method1();
    item.method2();
}

fn main() {
    let my_struct = MyStruct;
    call_methods(&my_struct);
}

1 Like

Rescript’s type system is a bit different, though usually you can get some of the same effects with Functors.

module type Base = {
  type t
}

module type Trait1 = (Base: Base) => {
  let function1: Base.t => unit
}

module type Trait2 = (Base: Base) => {
  let function2: Base.t => unit
}

module AllTogether = (Base: Base, Impl1: Trait1, Impl2: Trait2) => {
  module M1 = Impl1(Base)
  module M2 = Impl2(Base)
  let callFunctions = t => {
    M1.function1(t)
    M2.function2(t)
  }
}

module MyModule = {
  type t = ()
}

module Impl1 = (Base: Base) => {
  let function1 = _ => Console.log("Method 1 called")
}

module Impl2 = (Base: Base) => {
  let function2 = _ => Console.log("Method 2 called")
}

module JointImpl = AllTogether(MyModule, Impl1, Impl2)

let value: MyModule.t = ()
JointImpl.callFunctions(value)

Now, this is a bit…much, and extending it out into a real use case would probably hit a wall quickly, but we’re talking about a toy example, so feel free to give more impl code you’d like to see Rescriptified. :wink:

2 Likes

Here’s a simpler and less flexible solution that might still be sufficient, and that avoids the complexity of functors:

module type Trait1 = {
  let function1: unit => unit
}

module type Trait2 = {
  let function2: unit => unit
}

module type Trait1And2 = {
  include Trait1
  include Trait2
}

let callFunctions = (module(M: Trait1And2)) => {
  M.function1()
  M.function2()
}

module MyModule = {
  let function1 = _ => Console.log("Method 1 called")
  let function2 = _ => Console.log("Method 2 called")
}

callFunctions(module(MyModule))
3 Likes