Overload params using traits

Notice that the number of arguments does not vary in this case.

struct Bar;

trait Foo<T> {
  fn foo(&self, val:T);
}

impl Foo<i32> for Bar {
  fn foo(&self, val:i32) {
    println!("int: {:?}", val);
  }
}

impl Foo<f32> for Bar {
  fn foo(&self, val:f32) {
    println!("float: {:?}", val);
  }
}

fn main() {
  let bar = Bar;
  bar.foo(14i32);
  bar.foo(0.5f32);
}

You can also implement a method on tuple, like this:

trait Foo {
  fn foo(&self);
}

impl Foo for (i32, i32) {
    fn foo(&self) {
        let (a, b) = *self;
        println!("two ints (sum = {})", a+b);
    }
}

impl Foo for (i32, i32, i32) {
    fn foo(&self) {
        let (a, b, c) = *self;
        println!("three ints (sum = {})", a+b+c);
    }
}

fn main() {
    (1, 2).foo();
    (1, 2, 3).foo();
}

Either way, it's not terribly ergonomic.