Eliminate union case remapping common in monadic functions
- Dominant language
- F#
- Stars
- 4.3k
- Forks
- 876
- Avg merge
- 4d 22h
- Merged PRs (30d)
- 144
Description
Consider an inlined version of `Result.map`
```fsharp
let inline map mapping result =
match result with
| Error e -> Error e
| Ok x -> Ok (mapping x)
let ff x = map (fun y -> y.ToString ()) x
let ffs x = map id x
```
The last 2 functions compiled down to
```csharp
public static FSharpResult ff(FSharpResult x)
{
if (x.Tag == 0)
{
a resultValue = x.ResultValue;
a a = resultValue;
return FSharpResult.NewOk(a.ToString());
}
return FSharpResult.NewError(x.ErrorValue);
}
public static FSharpResult ffs(FSharpResult x)
{
if (x.Tag == 0)
{
return FSharpResult.NewOk(x.ResultValue);
}
return FSharpResult.NewError(x.ErrorValue);
}
```
In both functions a new error case is allocated. This is necessary in `ff` (and in the original `map`), because the input result type is `Result<'a, 'b>` and the output is `Result`. However, input and output types are the same in `ffs`, so the original union case can simply pass through instead of being recreated.
```csharp
public static FSharpResult ffs(FSharpResult x)
{
if (x.Tag == 0)
{
return FSharpResult.NewOk(x.ResultValue);
}
return x; // <---------
}
```
Contributor guide
Assessment
This issue has not been assessed yet.