Closed joaquinrovira closed 8 months ago
Your proposal would be to create UnitResult
, as an alias for Result[Unit]
? Or a completely different monad type?
Can you provide some examples of UnitResult
being much easier to use than err == nil
?
TL;DR: Disregard, after doing some more reading I realize the current version of Go does not accomodate what I am trying to achieve.
I am relatively new to FP concepts and the use of Monads, so there might be better ways to tackle the issue that I am not seeing. The scenario that led me to post this issue is when chaining function calls in and I want to make use of the build-in error handling of Result
. Given the following functions:
type A struct { ... }
type B struct { ... }
func GetA() (A, error) { ... }
func UseA(a A) error { ... }
func GetB() (B, error) { ... }
func UseB(b B) error { ... }
func DoWork() error {
a, err := GetA()
if err != nil {
return err
}
err = UseA(a)
if err != nil {
return err
}
b, err := GetB()
if err != nil {
return err
}
err = UseB(b)
if err != nil {
return err
}
return nil
}
func main() {
err := DoWork()
// ...
}
I would like to use the Result
monad to more succinctly express the DoWork()
function - avoiding the need for all those explicit if err != nil
checks. Ideally I would like to write something similar to:
func DoWork() UnitResult {
return Try(GetA).
MapUnit(UseA). // func (r Result[T]) MapUnit(mapper func(value T) error) UnitResult
Map(GetB). // func (r UnitResult) Map[T2 any](mapper func(value T) (T2, error)) Result[T2]
MapUnit(UseB) // func (r Result[T]) MapUnit(mapper func(value T) error) UnitResult
}
After doing some research I have come to realize that struct methods do not allow for generics so this would be impossible to implement right now. (https://github.com/golang/go/issues/49085)
Oh! Yes, unfortunately, this is the major limitation of this library.
Trust me, as soon as it is possible in go, this library will get a v2 😆
Unfortunately, some dude in the Go core team don't want to push it forward :-(
Context:
The current implementation of the Result monad in our functional programming library for Golang provides a robust mechanism for handling success and failure scenarios in functions. However, it lacks explicit support for functions that return no result on success, commonly known as "void" functions.
Proposal:
I propose extending the existing Result monad to include explicit support for void functions. This enhancement would enable users to represent and handle successful outcomes where the function does not explicitly return a result.
Requirements:
The extended Result monad should be able to accommodate both functions that return a value on success and functions that don't. This could involve introducing a new type or modifying the existing Result type to support both scenarios.
Use Case:
Consider a scenario where a function is responsible for updating a database record and does not return any value upon success. Currently, users have to resort to using nil or other ad-hoc solutions, which can lead to ambiguity and decreased code readability.
Example:
Benefits:
I look forward to community feedback and discussions on this proposed enhancement.
Thank you!