diff --git a/fn/result.go b/fn/result.go index 11d2d82a4..cb459bdc8 100644 --- a/fn/result.go +++ b/fn/result.go @@ -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) + }) + }) +}