Monads and popular FP abstractions, powered by Go 1.18+ Generics (Option, Result, Either...)
Monads and popular FP abstractions, powered by Go 1.18+ Generics (Option, Result, Either...)
samber/mo brings monads and popular FP abstractions to Go projects. samber/mo uses the recent Go 1.18+ Generics.
Inspired by:
See also:
Why this name?
I love short name for such utility library. This name is similar to "Monad Go" and no Go package uses this name.
We currently support the following data types:
Option[T] (Maybe)Result[T]Either[A, B]EitherX[T1, ..., TX] (With X between 3 and 5)Future[T]IO[T]IOEither[T]Task[T]TaskEither[T]State[S, A]go get github.com/samber/mo@v1
# AI Agent Skill
npx skills add https://github.com/samber/cc-skills-golang --skill golang-samber-mo
This library is v1 and follows SemVer strictly.
No breaking changes will be made to exported APIs before v2.0.0.
This library has no dependencies except the Go std lib.
You can import mo using:
import (
"github.com/samber/mo"
)
Quick example using the option sub-package Pipe3 to compose transformations:
import (
"github.com/samber/mo"
"github.com/samber/mo/option"
)
out := option.Pipe3(
mo.Some(21),
option.Map(func(v int) int { return v * 2 }),
option.FlatMap(func(v int) mo.Option[int] { return mo.None[int]() }),
option.Map(func(v int) int { return v + 21 }),
)
// out == None[int]
Then use one of the helpers below:
…
More examples in documentation.
I cannot recommend it, but in case you are too lazy for repeating mo. everywhere, you can import the entire library into the namespace.
import (
. "github.com/samber/mo"
)
I take no responsibility on this junk.
GoDoc: https://godoc.org/github.com/samber/mo
Option is a container for an optional value of type T. If value exists, Option is of type Some. If the value is absent, Option is of type None.
Implements:
mo.Foldable[T, U]Constructors:
mo.Some() doc - playmo.None() doc - playmo.TupleToOption() doc - playmo.EmptyableToOption() doc - playmo.PointerToOption() doc - playMethods:
.IsPresent() doc - play.IsSome() doc - play.IsAbsent() doc - play.IsNone() doc - play.Size() doc - play.Get() doc - play.MustGet() doc - play.OrElse() doc - play.OrEmpty() doc - play.ToPointer() doc - play.ForEach() doc.Match() doc - play.Map() doc - play.MapNone() doc - play.MapValue() doc.FlatMap() doc - play.MarshalJSON() doc.UnmarshalJSON() doc.MarshalText() doc.UnmarshalText() doc.MarshalBinary() doc.UnmarshalBinary() doc.GobEncode() doc.GobDecode() doc.Scan() doc.Value() docOther:
mo.Fold[T, U, R any](f Foldable[T, U], successFunc func(U) R, failureFunc func(T) R) R docSub-package option (transformations and pipes):
option.Map()() docoption.FlatMap()() docoption.Match()() docoption.FlatMatch()() docoption.Pipe1..Pipe10() docsResult respresent a result of an action having one of the following output: success or failure. An instance of Result is an instance of either Ok or Err. It could be compared to Either[error, T].
Implements:
mo.Foldable[T, U]Constructors:
mo.Ok() doc - playmo.Err() doc - playmo.Errf() doc - playmo.TupleToResult() doc - playmo.Try() doc - playMethods:
.IsOk() doc - play.IsError() doc - play.Error() doc - play.Get() doc - play.MustGet() doc - play.OrElse() doc - play.OrEmpty() doc - play.ToEither() doc - play.ForEach() doc - play.Match() doc - play.Map() doc - play.MapValue() doc - play.MapErr() doc - play.FlatMap() doc - playOther:
mo.Fold[T, U, R any](f Foldable[T, U], successFunc func(U) R, failureFunc func(T) R) R docmo.Do[T any](fn func() T) (result mo.Result[T]) docSub-package result (transformations and pipes):
result.Map()() docresult.FlatMap()() docresult.Match()() docresult.FlatMatch()() docresult.Pipe1..Pipe10() docsEither represents a value of 2 possible types. An instance of Either is an instance of either A or B.
Implements:
mo.Foldable[T, U]Constructors:
Methods:
.IsLeft() doc.IsRight() doc.Left() doc.Right() doc.MustLeft() doc.MustRight() doc.Unpack() doc.LeftOrElse() doc.RightOrElse() doc.LeftOrEmpty() doc.RightOrEmpty() doc.Swap() doc.ForEach() doc.Match() doc.MapLeft() doc.MapRight() docOther:
mo.Fold[T, U, R any](f Foldable[T, U], successFunc func(U) R, failureFunc func(T) R) R docSub-package either (transformations and pipes):
either.MapLeft()() doceither.MapRight()() doceither.Match()() doceither.Swap()() doceither.Pipe1..Pipe10() docsType transformations in Map
Weird function signature on `(mo.Option).Map`
Result[T] return signature in functions `result.Match` and `resultMapErr`
Transforming return type when using map
Option JSON serialization/deserialization does not handle the null case correctly
Decoding BSON values
Add Helper function that would work like Either.Match but would return another type
v1.13.0 changed supported generic types for Option and driver.Valuer interface
Feature Request: (or How-To) about call a method on Foldable when "T", "U" inherit from same interface
Translating types