samber / mo

🦄 Monads and popular FP abstractions, powered by Go 1.18+ Generics (Option, Result, Either...)
https://pkg.go.dev/github.com/samber/mo
MIT License
2.61k stars 85 forks source link

Implement options package for cross-type transformations #4

Open Fryuni opened 2 years ago

Fryuni commented 2 years ago

As stated on the package doc:

The functions provided by this package are not methods of mo.Option due to the lack of method type parameters on methods. This is part of the design decision of the Go's generics as explained here: https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#No-parameterized-methods

Providing these methods as a separate package also matches Go's primitives and standard library:

  • The string type don't have methods, but there we have the strings package.
  • The []byte type don't have methods, but there we have the bytes package.
  • The io.Reader defines a single method, and all manipulations of a reader is done on packages io and ioutil.

This package includes:

The FlatMatch function is to replace this pattern:

var thing ExpensiveThing
if opt.IsPresent() {
  thing = NewExpensiveThingFrom(opt.MustGet())
} else {
  thing = NewExpensiveThing()
}

// Can now be done like this:

thing := options.FlatMatch(opt, NewExpensiveThingFrom, NewExpensiveThing)

I would have this be the behavior of Match and return an Option when wanted, but since there is already a method that use the two return values I decided to have the same signature for the function with same name and create a new function for this pattern. I called it FlatMatch since it allows the same use case as FlatMap, where the given functions return an Option and the result is that same Option.

If you agree with this idea I can send a results package right away.

Fryuni commented 2 years ago

Just found that what I called FlatMatch is called map_or_else in Rust. It might be a better name.

Fryuni commented 2 years ago

@samber any thoughts about this?