Module outcome
Outcome: Functional and composable option and result types for Lua.
local outcome = require "outcome"
Class Option
Option:isSome () | Returns true if the option contains a value. |
Option:isNone () | Returns true if the option value is nil. |
Option:ifSome (consumer) | Invokes a method with the value if Some. |
Option:ifNone (consumer) | Invokes a method if the option value is None. |
Option:unwrap () | Returns the value if Some, or throws an error. |
Option:unwrapOr (defaultValue) | Unwraps and returns the value if Some, or returns default value. |
Option:unwrapOrElse (valueProvider) | Unwraps and returns the value if Some, or returns the result of invoking a function that when called returns a value. |
Option:expect (message) | Unwraps and returns the value if Some, or raises a specific error. |
Option:andOther (other) | Returns other if the option value is Some, otherwise returns self. |
Option:orOther (other) | Returns self if a value is Some, otherwise returns other . |
Option:orElseOther (f) | Returns self if a value is Some, otherwise returns the result of f. |
Option:map (f) | Maps an Option<T> to Option<U> by applying a function to the contained
value. |
Option:mapOr (defaultValue, f) | Applies a function to the contained value (if any), or returns a default. |
Option:mapOrElse (defaultProvider, mapFunction) | Applies a function to the contained value (if any), or computes a default. |
Option:flatmap (f) | Returns an None option if the option value is not preset. |
Option:filter (f) | Filters a Some Option through f and if f returns false, creates a
None Option. |
Option:okOr (err) | Transforms the Option<T> into a Result<T, E> , mapping a Some value to
an Ok Result, and an None value to Result err. |
Option:okOrElse (errorProvider) | Transforms the Option<T> into a Result<T, E> , mapping a Some value
to an Ok Result, and an None value to Result err. |
Class Result
Result:isOk () | Returns true if the result is Ok. |
Result:isErr () | Returns true if the result is an error. |
Result:ifOk (consumer) | Invokes a method with the value if the Result is Ok. |
Result:ifErr (consumer) | Invokes a method if the Result is an Err and passes the error to consumer. |
Result:unwrap () | Returns the value if Ok, or raises an error using the error value. |
Result:unwrapErr () | Unwraps a result, yielding the content of an Err. |
Result:unwrapOr (defaultValue) | Unwraps and returns the value if Ok, or returns default value. |
Result:unwrapOrElse (valueProvider) | Unwraps and returns the value if Ok, or returns the result of invoking a method that when called returns a value. |
Result:expect (message) | Unwraps and returns the value if Ok, or errors with a message. |
Result:andOther (other) | Returns other if the result is Ok, otherwise returns the Err value of self. |
Result:orOther (other) | Returns other if the result is Err, otherwise returns self. |
Result:orElseOther (resultProvider) | Calls resultProvider if the result is Err, otherwise returns self. |
Result:map (f) | Maps a Result<T, E> to Result<U, E> by applying a function to a
contained Ok value, leaving an Err value untouched. |
Result:mapErr (f) | Maps a Result<T, E> to Result<T, F> by applying a function to a
contained Err value, leaving an Ok value untouched. |
Result:flatmap (f) | Calls f if the result is Ok, otherwise returns the Err value of self. |
Result:okOption () | Converts from Result<T, E> to Option<T> . |
Result:errOption () | Converts from Result<T, E> to Option<E> . |
Option functions
option (value) | Returns either a None or Some Option based on if the value == nil. |
some (value) | Create a new Option, wrapping a value. |
none () | Returns a None Option. |
Result functions
ok (value) | Create a new Ok Result. |
err (value) | Create a new Err Result. |
pcall (f, Arguments) | Invokes a function and returns a Result<T, E> . |
Class Option
Option type.
The Option class is used as a functional replacement for null. Using Option provides a composable mechanism for working with values that may or may not be present. This Option implementation is heavily inspired by the Option type in Rust, and somewhat by the Optional type in Java.
Examples
local outcome = require "outcome"
-- Options are either Some or None.
assert(outcome.none():isNone())
assert(outcome.some("foo"):isSome())
-- You can map over the value in an Option.
local result = outcome.some(1)
:map(function(value) return value + 1 end)
:unwrap()
assert(result == 2)
-- Raises an error with the message provided in expect.
outcome.none():expect("Expected a value"):
-- You can provide a default value when unwrapping an Option.
assert("foo" == outcome.none():unwrapOr("foo"))
- Option:isSome ()
-
Returns true if the option contains a value.
Returns:
-
bool
- Option:isNone ()
-
Returns true if the option value is nil.
Returns:
-
bool
- Option:ifSome (consumer)
-
Invokes a method with the value if Some. The return value of the function is ignored.
local opt = outcome.some("abc") opt:ifSome(function(value) print(value) end)
Parameters:
- consumer function Consumer to invoke with a side effect.
Returns:
-
Option
Returns self.
- Option:ifNone (consumer)
-
Invokes a method if the option value is None. The return value of the function is ignored.
local opt = outcome.none() opt:ifNone(function(value) print("It's None!") end)
Parameters:
- consumer function Method to invoke if the value is None.
Returns:
-
Option
Returns self.
- Option:unwrap ()
-
Returns the value if Some, or throws an error.
Returns:
-
T the wrapped option.
- Option:unwrapOr (defaultValue)
-
Unwraps and returns the value if Some, or returns default value.
local opt = outcome.none() assert("foo", opt:unwrapOr("foo"))
Parameters:
- defaultValue Default value T to return.
Returns:
-
T returns the wrapped value or the default.
- Option:unwrapOrElse (valueProvider)
-
Unwraps and returns the value if Some, or returns the result of invoking a function that when called returns a value.
local opt = outcome.none() assert("foo", opt:unwrapOrElse(function() return "foo" end))
Parameters:
- valueProvider function to invoke if the value is None.
Returns:
-
T returns the wrapped value or the value returned from valueProvider.
- Option:expect (message)
-
Unwraps and returns the value if Some, or raises a specific error.
local option = outcome.some("foo") local value = option:expect("Error message")
Parameters:
- message string Message to raise.
Returns:
-
T returns the wrapped value.
- Option:andOther (other)
-
Returns
other
if the option value is Some, otherwise returns self.local optA = outcome.some("abc") local optB = outcome.some("123") assert(optB = optA:andOther(optB))
Parameters:
- other
Option
Alternative
Option<T>
to return.
Returns:
-
Option
Returns
Option<T>
- other
Option
Alternative
- Option:orOther (other)
-
Returns self if a value is Some, otherwise returns
other
.local optA = outcome.none() local optB = outcome.some("123") assert(optB = optA:orOther(optB))
Parameters:
- other
Option
Alternative
Option<T>
to return.
Returns:
-
Option
Returns
Option<T>
- other
Option
Alternative
- Option:orElseOther (f)
-
Returns self if a value is Some, otherwise returns the result of f.
local optA = outcome.none() local optB = optA:orElseOther(function() return outcome.some("123") end) assert(optB:unwrap() == "123")
Parameters:
- f
function
Function that returns an
Option<T>
.
Returns:
-
Option
Returns
Option<T>
- f
function
Function that returns an
- Option:map (f)
-
Maps an
Option<T>
toOption<U>
by applying a function to the contained value.local value outcome.some(1) :map(function(value) return value + 1 end) :unwrap() assert(value == 2)
Parameters:
- f function Function that accepts T and returns U.
Returns:
-
Option
Returns
Option<U>
- Option:mapOr (defaultValue, f)
-
Applies a function to the contained value (if any), or returns a default.
local value outcome.some("foo") :mapOr("baz", function(value) return value .. " test" end) :unwrap() assert(value == "foo test") value outcome.none() :mapOr("baz", function(value) return value .. " test" end) :unwrap() assert(value == "baz")
Parameters:
- defaultValue Value U to return if the option is None.
- f function Function that accepts T and returns U.
Returns:
-
Option
Returns
Option<U>
- Option:mapOrElse (defaultProvider, mapFunction)
-
Applies a function to the contained value (if any), or computes a default.
local mapFunction = function(value) return value .. "test" end) local value outcome.some("foo") :mapOr(function() return "baz" end), mapFunction) :unwrap() assert(value == "foo test") value outcome.none() :mapOr(function() return "baz" end), mapFunction) :unwrap() assert(value == "baz")
Parameters:
- defaultProvider function Default function to invoke that returns U.
- mapFunction function Function that accepts T and returns U.
Returns:
-
Option
Returns
Option<U>
- Option:flatmap (f)
-
Returns an None option if the option value is not preset. Otherwise calls f with the wrapped value and returns the result.
local value = outcome.some(1) :flatmap(function(value) return outcome.some(value + 1) end) :unwrap() assert(value == 2)
Parameters:
- f
function
Function that accepts T and returns
Option<U>
.
Returns:
-
Option
Returns
Option<U>
- f
function
Function that accepts T and returns
- Option:filter (f)
-
Filters a Some Option through
f
and iff
returns false, creates a None Option. None Option is returned as-is and not passed tof
.Parameters:
- f function Filter function that receives a value and returns bool.
Returns:
-
Option
Returns
Option<T>
- Option:okOr (err)
-
Transforms the
Option<T>
into aResult<T, E>
, mapping a Some value to an Ok Result, and an None value to Result err.local res = outcome.some(1):okOr("error data if None") assert(res:isOk()) assert(res:unwrap() == 1)
Parameters:
- err function Error to use in the Result if the value is None.
Returns:
-
Result
Returns
Result<T, E>
- Option:okOrElse (errorProvider)
-
Transforms the
Option<T>
into aResult<T, E>
, mapping a Some value to an Ok Result, and an None value to Result err.local res = outcome.some(1):okOrElse(function() return "error data if None" end) assert(res:isOk()) assert(res:unwrap() == 1)
Parameters:
- errorProvider function Function that returns E.
Returns:
-
Result
Returns
Result<T, E>
Class Result
Result<T, E>
is a type used for returning and propagating errors.
There are two kinds of Result objects:
- Ok: the result contains a successful value.
- Err: The result contains an error value.
Examples
local outcome = require "outcome"
local Result = outcome.Result
-- Results are either Ok or Err.
assert(outcome.ok("ok value"):isOk())
assert(outcome.err("error value"):isErr())
-- You can map over the Ok value in a Result.
local result = outcome.ok(1)
:map(function(value) return value + 1 end)
:unwrap()
assert(result == 2)
-- Raises an error with the message provided in expect.
outcome.err("error value"):expect("Result was not Ok"):
-- You can provide a default value when unwrapping a Result.
assert("foo" == outcome.err("error value"):unwrapOr("foo"))
- Result:isOk ()
-
Returns true if the result is Ok.
Returns:
-
bool
- Result:isErr ()
-
Returns true if the result is an error.
Returns:
-
bool
- Result:ifOk (consumer)
-
Invokes a method with the value if the Result is Ok. The return value of
the function is ignored.
Parameters:
- consumer function Consumer to invoke with a side effect.
Returns:
-
Option
Returns self.
- Result:ifErr (consumer)
-
Invokes a method if the Result is an Err and passes the error to consumer.
The return value of the function is ignored.
Parameters:
- consumer function Method to invoke if the value is error.
Returns:
-
Option
Returns self.
- Result:unwrap ()
-
Returns the value if Ok, or raises an error using the error value.
Returns:
-
T the wrapped result value.
Raises:
Errors with if the result is Err. - Result:unwrapErr ()
-
Unwraps a result, yielding the content of an Err.
Returns:
-
E the error value.
Raises:
Errors if the value is Ok. - Result:unwrapOr (defaultValue)
-
Unwraps and returns the value if Ok, or returns default value.
Parameters:
- defaultValue Default value T to return.
Returns:
-
T returns the wrapped value or the default.
- Result:unwrapOrElse (valueProvider)
-
Unwraps and returns the value if Ok, or returns the result of invoking
a method that when called returns a value.
Parameters:
- valueProvider function Function to invoke if the value is an error.
Returns:
-
T returns the Ok value or the value returned from valueProvider.
- Result:expect (message)
-
Unwraps and returns the value if Ok, or errors with a message.
Parameters:
- message string Message to include in the error.
Returns:
-
T returns the wrapped value.
- Result:andOther (other)
-
Returns other if the result is Ok, otherwise returns the Err value of self.
Parameters:
- other
Result
Result<T, E>
other Alternative Result to return.
Returns:
-
Result
Returns
Result<T, E>
- other
Result
- Result:orOther (other)
-
Returns other if the result is Err, otherwise returns self.
local value = outcome.err("error!") :orOther(outcome.ok(1)) :unwrap() assert(value == 1) value = outcome.ok(1) :orOther(outcome.ok(999)) :unwrap() assert(value == 1)
Parameters:
- other
Result
Result<T, E>
other Alternative Result to return.
Returns:
-
Result
Returns
Result<T, E>
- other
Result
- Result:orElseOther (resultProvider)
-
Calls resultProvider if the result is Err, otherwise returns self.
This function can be used for control flow based on result values.
local value = outcome.err("error!") :orElseOther(function(v) return outcome.ok(1) end) :unwrap() assert(value == 1) value = outcome.ok(1) :orElseOther(function(v) return outcome.ok(999) end) :unwrap() assert(value == 1)
Parameters:
- resultProvider
function
Function that returns
Result<T, E>
.
Returns:
-
Result
Returns
Result<T, E>
- resultProvider
function
Function that returns
- Result:map (f)
-
Maps a
Result<T, E>
toResult<U, E>
by applying a function to a contained Ok value, leaving an Err value untouched.This function can be used to compose the results of two functions.
local value = outcome.ok(1) :map(function(v) return v + 1 end) :unwrap() assert(value == 2)
Parameters:
- f
function
Function that accepts
T
and returnsU
.
Returns:
-
Result
Returns
Result<U, E>
- f
function
Function that accepts
- Result:mapErr (f)
-
Maps a
Result<T, E>
toResult<T, F>
by applying a function to a contained Err value, leaving an Ok value untouched.This function can be used to pass through a successful result while handling an error.
local value = outcome.err(1) :mapErr(function(v) return v + 1 end) :unwrapErr() assert(value == 2)
Parameters:
- f
function
Function that accepts
E
and returnsU
.
Returns:
-
Result
Returns
Result<T, F>
- f
function
Function that accepts
- Result:flatmap (f)
-
Calls f if the result is Ok, otherwise returns the Err value of self.
This function can be used for control flow based on Result values.
local value = outcome.ok(1) :flatmap(function(v) return outcome.ok(v + 1) end) :unwrap() assert(value == 2)
Parameters:
- f
function
Function that accepts T and returns
Result<T. E>
.
Returns:
-
Result
Returns
Result<T, E>
- f
function
Function that accepts T and returns
- Result:okOption ()
-
Converts from
Result<T, E>
toOption<T>
. Converts self into anOption<T>
, consuming self, and discarding the error, if any.Returns:
-
Result
Returns
Result<T, E>
- Result:errOption ()
-
Converts from
Result<T, E>
toOption<E>
. Converts self into anOption<E>
, consuming self, and discarding the success value, if any.Returns:
-
Result
Returns
Result<T, E>
Option functions
- option (value)
-
Returns either a None or Some Option based on if the value == nil.
local opt = outcome.option(nil) assert(opt:isNone()) local opt = outcome.option("foo") assert(opt:isSome())
Parameters:
- value
Returns:
-
Option
Returns
Option<T>
- some (value)
-
Create a new Option, wrapping a value. If the provided value is nil, then the Option is considered None.
local opt = outcome.some("abc") assert(opt:isSome()) assert("abc" == opt:unwrap())
Parameters:
- value Value T to wrap.
Returns:
-
Option
Option<T>
- none ()
-
Returns a None Option.
local opt = outcome.none() assert(opt:isNone())
Returns:
-
Option
Returns
Option<T>
Result functions
- ok (value)
-
Create a new Ok Result.
local res = outcome.ok("foo") assert(res:isOk()) assert(res:unwrap() == "foo")
Parameters:
- value T Ok value to wrap.
Returns:
-
Result
Returns
Result<T, E>
- err (value)
-
Create a new Err Result.
local res = outcome.err("error message") assert(res:isErr()) assert(res:unwrapErr() == "message") -- Err values can be of any type. local resWithComplexErr = outcome.err({foo = true}) assert(resWithComplexErr:isErr()) assert(resWithComplexErr:unwrapErr().foo == true)
Parameters:
- value T Error value to wrap.
Returns:
-
Result
Returns
Result<T, E>
- pcall (f, Arguments)
-
Invokes a function and returns a
Result<T, E>
. If the function errors, an Err Result is returned.local res = Result.pcall(error, "oh no!") assert(res:isErr()) assert(res:unwrapErr() == "oh no!")
Parameters:
- f function Function to invoke that returns T or raises E.
- Arguments ... to pass to the function.
Returns:
-
Result
Returns
Result<T, E>