fn: add additional utility methods for Result[T]

`NewResult` makes it easy to wrap a normal function call in a result
value.

`Err` can be used to check the error case of the result without
unpacking the entire thing.

`AndThen2` allows a caller to compose a function on two results values,
with the closure only executing if both values are non-error.
This commit is contained in:
Olaoluwa Osuntokun 2024-06-20 15:03:57 -07:00
parent 390f0723d3
commit f1a38714d4
No known key found for this signature in database
GPG Key ID: 3BBD59E99B280306

View File

@ -10,6 +10,15 @@ type Result[T any] struct {
Either[T, error]
}
// NewResult creates a new result from a (value, error) tuple.
func NewResult[T any](val T, err error) Result[T] {
if err != nil {
return Err[T](err)
}
return Ok(val)
}
// Ok creates a new Result with a success value.
func Ok[T any](val T) Result[T] {
return Result[T]{Either: NewLeft[T, error](val)}
@ -33,6 +42,11 @@ func (r Result[T]) Unpack() (T, error) {
return r.left.UnwrapOr(zero), r.right.UnwrapOr(nil)
}
// Err exposes the underlying error of the result type as a normal error type.
func (r Result[T]) Err() error {
return r.right.some
}
// IsOk returns true if the Result is a success value.
func (r Result[T]) IsOk() bool {
return r.IsLeft()
@ -140,3 +154,15 @@ func FlatMap[A, B any](r Result[A], f func(A) Result[B]) Result[B] {
func AndThen[A, B any](r Result[A], f func(A) Result[B]) Result[B] {
return FlatMap(r, f)
}
// AndThen2 applies a function that returns a Result[C] to the success values
// of two Result types if both exist.
func AndThen2[A, B, C any](ra Result[A], rb Result[B],
f func(A, B) Result[C]) Result[C] {
return AndThen(ra, func(a A) Result[C] {
return AndThen(rb, func(b B) Result[C] {
return f(a, b)
})
})
}