Of course when used like in your example it’s uglier. But you shouldn’t use it like that anyways.
I’d probably write it like this:
myFunction.map(
() -> {}, // success
() -> {} // error
);
and the second example would actually look the same, just that the return value is different. No need to wrap it again in a new result.
The advantage is when looking at the method signature.
public SuccessValue readFile(); // no idea what exceptions could be thrown
public Return<SuccessValue, ErrorValue> readFile(); // here I know
Generally, when you use an “if” with a result type, then you’re using it wrong.
Depending on the language, it might even behave almost the same way as with exceptions.
For example Promises in Javascript are the same thing and using async-await, you can still write code like before (without mapping), but the return value will then be another Promise<X> instead of just X.