Result module regularity with option/voption
I propose we extend the Result module to add APIs which exist for option/voption in FSharp.Core already.
The Result type's dual nature (Ok/Error) makes some Option APIs less applicable
The missing APIs that would improve Result ergonomics:
orElseorElseWithtoSeq- since toList and toArray is there already
API Comparison: Result vs Option/ValueOption
APIs Missing from Result but Present in Option/ValueOption
| API | Option | ValueOption | Result | Should Add? | Reasoning |
|---|---|---|---|---|---|
orElse |
✓ | ✓ | ✗ | ✓ | Makes sense - would return first Ok or fallback Result |
orElseWith |
✓ | ✓ | ✗ | ✓ | Makes sense - lazy evaluation for fallback Result |
get |
✓ | ✓ | ✗ | ✗ | Unsafe - Result should encourage proper error handling |
toSeq |
✓ | ✓ | ✗ | ✓ | Convert to sequence |
ofNullable |
✓ | ✓ | ✗ | ✗ | Would need to specify what Error value to use for null |
toNullable |
✓ | ✓ | ✗ | ✗ | Feels similar to get, also symmetrical ofNullable (above) missing anyway |
The existing way of approaching this problem in F# is to write it yourself.
Pros and Cons
The advantages of making this adjustment to F# are easier access for beginners.
The disadvantages of making this adjustment to F# are cost of more code to maintain and ship
Extra information
Estimated cost (XS, S, M, L, XL, XXL): S
Affidavit (please submit!)
Please tick these items by placing a cross in the box:
- [x] This is not a question (e.g. like one you might ask on StackOverflow) and I have searched StackOverflow for discussions of this issue
- [x] This is a language change and not purely a tooling change (e.g. compiler bug, editor support, warning/error messages, new warning, non-breaking optimisation) belonging to the compiler and tooling repository
- [x] This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it
- [x] I have searched both open and closed suggestions on this site and believe this is not a duplicate
Please tick all that apply:
- [x] This is not a breaking change to the F# language design
- [x] I or my company would be willing to help implement and/or test this
For Readers
If you would like to see this issue implemented, please click the :+1: emoji on this issue. These counts are used to generally order the suggestions by engagement.
I'd like to zoom in on orElseWith. We should have the same semantics as we did with defaultWith in https://github.com/fsharp/fslang-suggestions/issues/1123#issuecomment-1179170318 which is to pass the 'error in rather than unit for the error path function. unit makes sense in the case of v/option types since None doesn't contain any information where as Result does.
For a more concrete example, here's the implementation from FsToolkit.ErrorHandling
let inline orElseWith
([<InlineIfLambda>] ifErrorFunc: 'error -> Result<'ok, 'errorOutput>)
(result: Result<'ok, 'error>)
: Result<'ok, 'errorOutput> =
match result with
| Ok x -> Ok x
| Error e -> ifErrorFunc e
Also, if we add ofNullable (and decide what to do for null), then surely we should also add ofOption with similar semantics.
There's also the ofObj / toObj pair.
Also, if we add
ofNullable(and decide what to do for null), then surely we should also addofOptionwith similar semantics.There's also the
ofObj/toObjpair.
FSharp.Core could provide a marker type for the TError value in case of incoming nulls/None/ValueNone.
But it would not compose well and I am afraid it would defeat the purpose of using Result (unless it is immediately fed into mapError)
Having the error value as an user-provided argument seems like a better choice:
type MyDomainErrors = FileNotFound | InputEmpty | ...
let x : string | null = null
let r = x |> Result.ofNullable InputEmpty
Having the error value as an user-provided argument seems like a better choice
Yeah, that's how I usually implement it in custom utils modules.
It also corresponds to FsToolkit.ErrorHandling's requireSome.