Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make the following code type safe?

Tags:

types

scala

say, I have a generic command trait with an execute method that takes an Input and returns an Output. Something like

trait Input;
trait Output;

trait Command[I <: Input, O <: Output] {
  def execute(input: I): O;
}

Then, I am going to create various Commands, something like

class SampleInput extends Input
class SampleOutput extends Output

class SampleCommand extends Command[SampleInput, SampleOutput] {
  def execute(input:SampleInput):SampleOutput = new SampleOutput()
}

The problem with this is I could create a Command with a SampleAInput and SampleBOutput and the compiler will accept that happily. How do I enforce that so the compiler fails with type mismatch error ?

Somehow, I need to group Input and Output under a type and pass that type to create a command. How do I do that?

like image 698
sanjib Avatar asked Dec 20 '10 03:12

sanjib


1 Answers

trait InputOutput {
  type Input
  type Output
}

trait Command[IO <: InputOutput] {
  def execute(input: IO#Input): IO#Output
}

Here's some usage:

scala> trait SampleIO extends InputOutput {type Input = String; type Output = String}
defined trait SampleIO

scala> class SampleCommand extends Command[SampleIO] {def execute(input: String) = input}
defined class SampleCommand

scala> class SampleCommand extends Command[SampleIO] {def execute(input: String) = 1}
<console>:13: error: type mismatch;
 found   : Int(1)
 required: SampleIO#Output
       class SampleCommand extends Command[SampleIO] {def execute(input: String) = 1}
                                                                                 ^
like image 178
IttayD Avatar answered Nov 15 '22 11:11

IttayD