Skip to content
bingmeow1999 edited this page Nov 30, 2020 · 3 revisions

Original Discussion Link

Description

I was writing this example to explain to my friend about PECS and I thought that it might be useful to share it since I already written it. Hopefully it can help someone out there.

This was written quickly so if I made any mistakes feel free to point it out. This is all just pseudo code so it won't compile.

// Input Class
class InputParent {}
class Input extends InputParent {}
class InputChild extends Input {}

// Output Class
class OutputParent {}
class Output extends OutputParent {}
class OutputChild extends Output {}

// Example Class
class Example {
    // Functor(s)
    Function<Input,            Output> a = (Input input)       -> { return new Output(); };
    Function<Input,       OutputChild> b = (Input input)       -> { return new OutputChild(); };
    Function<InputParent,      Output> c = (InputParent input) -> { return new Output(); };
    Function<InputParent, OutputChild> d = (InputParent input) -> { return new OutputChild(); };
    Function<InputChild, OutputParent> e = (InputChild input)  -> { return new OutputParent(); };
    Function<Object,      OutputChild> o = (Object input)      -> { return new OutputChild(); };

    // Function(s)
    Output In_Out(Input input, Function<Input, Output> f) {
        return f.apply(input);
    }

    Output In_OutExtends(Input input, Function<Input, ? extends Output> f) {
        return f.apply(input);
    }

    Output InSuper_Out(Input input, Function<? super Input, Output> f) {
        return f.apply(input);
    }

    Output InSuper_OutExtends(Input input, Function<? super Input, ? extends Output> f) {
        return f.apply(input);
    }

    // Example Use Case
    Output GetOutput() {
        // This is my input. By giving this input, I want an Output.
        Input input = new Input();
        
        // I shall provide my Input. And I shall receive an Output.
        Output output = In_Out(input, a); // Compiles
        Output output = In_Out(input, b); // Compile Error
        Output output = In_Out(input, c); // Compile Error
        Output output = In_Out(input, d); // Compile Error
        Output output = In_Out(input, e); // Compile Error
        Output output = In_Out(input, o); // Compile Error

        Output output = In_OutExtends(input, a); // Compiles
        Output output = In_OutExtends(input, b); // Compiles
        Output output = In_OutExtends(input, c); // Compile Error
        Output output = In_OutExtends(input, d); // Compile Error
        Output output = In_OutExtends(input, e); // Compile Error
        Output output = In_OutExtends(input, o); // Compile Error

        Output output = InSuper_Out(input, a); // Compiles
        Output output = InSuper_Out(input, b); // Compile Error
        Output output = InSuper_Out(input, c); // Compiles
        Output output = InSuper_Out(input, d); // Compile Error
        Output output = InSuper_Out(input, e); // Compile Error
        Output output = InSuper_Out(input, o); // Compile Error

        Output output = InSuper_OutExtends(input, a); // Compiles
        Output output = InSuper_OutExtends(input, b); // Compiles
        Output output = InSuper_OutExtends(input, c); // Compiles
        Output output = InSuper_OutExtends(input, d); // Compiles
        Output output = InSuper_OutExtends(input, e); // Compile Error
        Output output = InSuper_OutExtends(input, o); // Compiles

        // I have gotten an output. Is it an Output, or perhaps OutputChild? Does not matter.
        return output;
    }
}

Clone this wiki locally