Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TaskResultOption compatibility with TaskResult and friends #259

Open
jozefRudy opened this issue Apr 2, 2024 · 4 comments
Open

TaskResultOption compatibility with TaskResult and friends #259

jozefRudy opened this issue Apr 2, 2024 · 4 comments
Labels
good first issue Good for newcomers

Comments

@jozefRudy
Copy link

jozefRudy commented Apr 2, 2024

Is your feature request related to a problem? Please describe.
We have multiple CEs, like Result, Option, Task, TaskResult, TaskResultOption.

I am relatively new to f#, but it seems to me that it is impractical to work with TaskResultOption CE, even though for single expression it's clearly nice. But if we have various levels of expressions, e.g. TaskResultOption followed by TaskResult/Result, and for them to be inside taskResultOption CE, we need to keep converting all following expressions to highest denominator (TaskResultOption).

here is a code snippet, where Mode.Parse is a Result and we need to convert it to TaskResultOption to be able to follow linearly and extract success result, same with LoadUniverseForStrategy, which is TaskResult (but not an Option):

for clarity these are signatures:

LoadLatestStrategyQueryResult: TaskResult<StrategyQueryResult option,exn>
Mode.Parse: s: string -> Result<Mode,exn>
LoadUniverseForStrategy: id: int -> TaskResult<IntUniverse,exn>
            taskResultOption {
                let! strategy = this.LoadLatestStrategyQueryResult()
                let! mode = Mode.Parse strategy.StrategyType |> TaskResult.ofResult |> TaskResult.map Some
                let! universe = this.LoadUniverseForStrategy strategy.Id |> TaskResult.map Some

                return

                    { Id = strategy.Id
                      Entry = strategy.Entry
                      Exit = strategy.Exit
                      Saved = strategy.Saved
                      Universe = universe
                      Mode = mode }
            }

Is some kind of smart CE possible, that in case of using TaskResultOption would work using let! on TaskResult and friends?
Following snippet would be ideal:

            taskResultOption {
                let! strategy = this.LoadLatestStrategyQueryResult()
                let! mode = Mode.Parse strategy.StrategyType
                let! universe = this.LoadUniverseForStrategy strategy.Id
                return

                    { Id = strategy.Id
                      Entry = strategy.Entry
                      Exit = strategy.Exit
                      Saved = strategy.Saved
                      Universe = universe
                      Mode = mode }
            }

Another option is using lower denominator like taskResult (and then conversion is simpler, but we need to resort to branching, which will become impractical once we need to pattern match more than once in a method):

            taskResult {
                let! strategy = this.LoadLatestStrategyQueryResult()

                match strategy with
                | None -> return None
                | Some s ->
                    let! mode = Mode.Parse s.StrategyType
                    let! universe = this.LoadUniverseForStrategy s.Id

                    return
                        Some
                            { Id = s.Id
                              Entry = s.Entry
                              Exit = s.Exit
                              Saved = s.Saved
                              Universe = universe
                              Mode = mode }
            }

Maybe this is just me being a novice and not seeing a straightforward way forward.

@TheAngryByrd TheAngryByrd added the good first issue Good for newcomers label Apr 2, 2024
@TheAngryByrd
Copy link
Collaborator

Yeah this particular CE doesn't have all the same niceness that all the others do. Any PRs would be appreciated here!

@jozefRudy
Copy link
Author

not sure if i am up to a task. Also, maybe unrelated, taskResult cannot extract from simple option with let! Any advice on this?

@TheAngryByrd
Copy link
Collaborator

taskResult cannot extract from simple option with let! Any advice on this?

Yeah TaskResult knows nothing about options. You'll have to convert the Option to a Result.

@jozefRudy
Copy link
Author

yes, makes sense using Result.requireSome as an example, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

2 participants