On 11/6/20 5:51 AM, Andrey Zherikov wrote:
I have auto function 'f' that might return either an error (with some
text) or a result (with some value). The problem is that the type of the
error is not the same as the type of result so compilation fails.
...
How can I make the original code compilable without templatizing
`failure` function?
Paul Backus has already replied to you so I am surprised he did not plug
is own package "SumType". Maybe it is modesty? This seems like an ideal
time to use this.
All of that being said, I tried to solve this for you using Paul's
SumType package and myself was initially stymied by the fact that the
implicit conversion of a `Success(T)` or `Failure` type did not work
within the ternary op expression*. I rewrote it with if/else which works
great and is only slightly more verbose than with ternary op.
```D
alias Result = SumType!(Success!int, Failure);
auto f(int i)
{
Result retval;
if (i > 0)
retval = Success!int(i);
else
retval = Failure("Sorry!");
return retval;
}
```
the above relies on suitable definition of `Success(T)` and `Failure`
structs, obviously.
* This fails due to different types within the same expression:
```
retval = i > 0 ? Success!int(i) : Failure("Sorry");
```
casting each to `Result` compiles, but is verbose:
```
return i > 0 ? cast(Result) Success!int(i) : cast(Result)
Failure("Sorry");
```
** Could someone more knowledgeable than me explain why implicit
conversion does not happen with the ternary op, but works fine with
if/else? Presumably, it is because the op returns a single type and
implicit conversion is performed after computing the expression's return
type? If this somehow worked, it would make the SumType package much
more ergonomic **