Add an either function to the Option and Result module #526

Open
rexcfnghk opened this Issue Dec 20, 2016 · 7 comments

Projects

None yet

6 participants

@rexcfnghk
rexcfnghk commented Dec 20, 2016 edited

Title of Suggestion

I propose we add an either function to the Option and Result module.

The existing way of approaching this problem in F# is to define it ourselves:

module Option
    let either some none = function
        | Some x -> some x
        | None -> none

module Result
    let either ok error = function
        | Ok x -> ok x
        | Error e -> error e

Pros and Cons

The advantages of making this adjustment to F# are

  • It is a typical usage of Option and Result to perform branching when the result is considered 'valid' (e.g. Some x/Ok x)

The disadvantages of making this adjustment to F# are

  • Extra API on both modules
  • Extra tests needed

Extra information

Estimated cost (XS, S, M, L, XL, XXL): XS

Related suggestions: (put links to related suggestions here)

Affadavit (must be submitted)

Please tick this by placing a cross in the box:

  • This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
  • I have searched both open and closed suggestions on this site and believe this is not a duplicate
  • 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.

Please tick all that apply:

  • This is not a breaking change to the F# language design
  • I would be willing to help implement and/or test this
  • I or my company would be willing to help crowdfund F# Software Foundation members to work on this
@vasily-kirichenko

I don't see any advantages over pattern matching here.

@rexcfnghk

@vasily-kirichenko there is an advantage that one can partially apply Option.either/Result.either to get a default error/success handling mechanism.

@kspeakman
kspeakman commented Dec 22, 2016 edited

I have to define or import these (particularly Result.either) in every project. It also is the basic building block for other functions (bind, map, tee, etc.) to support functional error handling. The either implementation is both simple and uncontroversial. The only issue I can see someone raising is the name "either". But it doesn't really matter what name is used as long as the name was appropriate to its function.

vs pattern matching

Pattern matching is pretty verbose on Result-returning operations.

match someOp input with
| Error err -> createErrorResponse err
| Ok opValue ->
    // dupe structure
    match nextOp opValue with
    | Error err -> createErrorResponse err // exactly duped line
    | Ok v -> createResponse v

// VERSUS

someOp input
|> Result.bind nextOp
|> Result.either createResponse createErrorResponse

// Result.bind defined as:
// let bind f = either f Error
@theprash

@kspeakman That nested pattern matching example isn't quite fair because you could use the existing Result.bind to avoid the nesting:

someOp input
|> Result.bind nextOp
|> function
| Ok v -> createResponse v
| Error e -> createErrorResponse e

It's still not as concise as either but at least it's not nested.

@kspeakman
kspeakman commented Dec 24, 2016 edited

@theprash That's a good point. I'm not using VS 2017 RC so Result doesn't exist for me yet, much less Result.bind.

Bottom line: either is useful at the end of a chain. It is also a building block to fill in other common functions that may not be defined by the F# core library. E.g. (Result.)bimap, tee, etc. You can define pretty much any other operation on these two types with either.

@jakubsuchybio

I don't know if I am wrong, but I think, that this would add value in Railway oriented programming ( more here: http://fsharpforfunandprofit.com/posts/recipe-part2/ )
It's a great way for propagating error without any hassle of nested matching.
Option is good, but having a message or data about the failure is sometimes critical to have.

@cartermp
Member

@jakubsuchybio This will be available in F# 4.1, where Result is a new type in FSharp.Core.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment