#Best strategy to enforce interface?

1 messages · Page 1 of 1 (latest)

zinc plume
#

I have a generic API that'll be implemented for several targets:

paint(target, color) { ... } -> Nil
get_color(target) { ... } -> Color

To make it easier to implement with exhaustiveness checks, I've decided to use a type for the different commands:

type Command {
  Paint(color)
  Get
}

fn execute(target, command) {
  case command {
    Paint(color) -> paint(target, color)
    // ...
  }
}

fn paint(target, color) {
  case target {
    Car(car) -> car.execute(car, Paint(color))
    Wall(wall) -> wall.execute(wall, Paint(color))
  }
}

This way when I write car or wall it's very easy to know which commands need implementing, and how complete is the implementation.

The problem I have is with return types. Since the commands return different values, I was struggling with what's the best approach to type that value.

I thought of using a generic like Command(returns), but then I'll have to add some field that denotes the returned value to every record.

Another option is to have a return type, but then I'll have to pattern match on the return value of every call.

Any suggestions?

scarlet cypress
#

You get stuck this way if you use types for actions

#

You’ll need to use functions for behaviour instead

#

Then each behaviour can have a different return type

frosty bluff
#

Yeah, I think the original API of separate functions is already good