Result type

A.k.a Either (Haskell)

Models a double-track Success/Failure

type Result<'Success, 'Error> = // 2 generic parameters
    | Ok of 'Success  // Success Track
    | Error of 'Error // Failure Track

Functional way of dealing with business errors (expected errors)

  • Allows exceptions to be used only for exceptional errors

  • As soon as an operation fails, the remaining operations are not launched

πŸ”— Railway-oriented programming (ROP)

Result module

Main functions:

map f result : to map the success β€’ ('T -> 'U) -> Result<'T, 'Error> -> Result<'U, 'Error>

mapError f result : to map the error β€’ ('Err1 -> 'Err2) -> Result<'T, 'Err1> -> Result<'T, 'Err2>

bind f result : same as map with f returning a Result β€’ ('T -> Result<'U, 'Error>) -> Result<'T, 'Error> -> Result<'U, 'Error> β€’ πŸ’‘ The result is flattened, like the flatMap function on JS arrays β€’ ⚠️ Same type of 'Error for f and the input result.

πŸ’‘ Since Fβ™― 7.0, more functions have been added to the Result module, but some functions are missing compared to the Option module:

Result
Option
List

Ok value

Some value

[ value ]

Error err

None

[ ]

Result.isOk / Result.isError

Option.isSome / Option.isNone

Γ— / List.isEmpty

Result.contains okValue

Option.contains someValue

List.contains value

Result.count

Option.count

List.length ❗ (O(N))

Result.defaultValue value

Option.defaultValue value

Γ—

Result.defaultWith defThunk

Option.defaultWith defThunk

Γ—

Γ—

Option.filter predicate

List.filter predicate

Result.iter action

Option.iter action

List.iter action

Result.map f

Option.map f

List.map f

Result.mapError f

Γ—

Γ—

Result.bind f

Option.bind f

List.bind f

Result.fold f state

Option.fold f state

List.fold f state

Result.toArray / toList

Option.toArray / toList

Γ—

Result.toOption

Γ—

Γ—

Quiz 🎲

Implement Result.map and Result.bind

πŸ’‘ Tips:

  • Map the Success track

  • Access the Success value using pattern matching

Solution

Success/Failure tracks

map: no track change

bind: eventual routing to Failure track, but never vice versa

☝ The mapping/binding operation is never executed in track Failure.

Result vs Option

Option can represent the result of an operation that may fail ☝ But if it fails, the option doesn't contain the error, just None

Option<'T> ≃ Result<'T, unit> β†’ Some x ≃ Ok x β†’ None ≃ Error () β†’ See Result.toOption (built-in) and Result.ofOption (below)

πŸ“… Dates

  • The Option type has been part of F# from the beginning

  • The Result type is more recent: introduced in F# 4.1 (2016)

πŸ“ Memory

  • The Option type (alias: option) is a regular union: a reference type

  • The Result type is a struct union: a value type

  • The ValueOption type (alias: voption) is a struct union: ValueNone | ValueSome of 't

Example

Let's change our previous checkAnswer to indicate the Error:

Last updated

Was this helpful?