I was trying to mimic some pattern matching behaviour in java:
interface Result<T>
{
<U> U eliminate(Function<T, U> f, BiFunction<Integer, String, U> g);
}
record Success<T>(T value) implements Result<T>
{
@Override public <U> U eliminate(Function<T, U> f, BiFunction<Integer, String, U> g)
{
return f.apply(value);
}
}
record Failure<T>(int errCode, String message) implements Result<T>
{
@Override public <U> U eliminate(Function<T, U> f, BiFunction<Integer, String, U> g)
{
return g.apply(errCode, message);
}
}
public class Main
{
public static void main(String[] args)
{
Result<Double> result = Result.success(4.0);
var log = result.eliminate(
value -> "Success: " + value,
(code, message) -> "Failure: " + code + " " + message
);
System.out.println(log);
}
}
The above would compile and run to output "Success: 4.0".
However when omitted the intermediate variable log and directly println its definition,
unless explicitly stating the return type of eliminate i.e. result.<String>eliminate(...),
java would suddenly not know what to do:
public class Main
{
public static void main(String[] args)
{
Result<Double> result = Result.success(4.0);
System.out.println(result.eliminate(
value -> "Success: " + value,
(code, message) -> "Failure: " + code + " " + message
));
}
}
% javac -Xdiags:verbose Main.java
Main.java:7: error: reference to println is ambiguous
System.out.println(result.eliminate(
^
both method println(char[]) in PrintStream and method println(String) in PrintStream match
Main.java:7: error: method println in class PrintStream cannot be applied to given types;
System.out.println(result.eliminate(
^
required: char[]
found: String
reason: argument mismatch; inference variable U has incompatible bounds
upper bounds: char[],Object
lower bounds: String
where U,T are type-variables:
U extends Object declared in method <U>eliminate(Function<T,U>,BiFunction<Integer,String,U>)
T extends Object declared in interface Result
2 errors
Edit: definition of Result.success
static <T> Result<T> success(T value) { return new Success<>(value); }
Since you seem to be returning the 'U' type. I'd switch out your 'type' and make it
Or just make it
Stringsince that's exactly what you're looking to return.Also, from a readability perspective, I'd create a 'Response' class that maps the value to message. If you're using Spring, you could use a
ResponseEnity. It makes it easier to read.