🦄 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
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"
)
Then use one of the helpers below:
option1 := mo.Some(42)
// Some(42)
option1.
FlatMap(func (value int) Option[int] {
return Some(value*2)
}).
FlatMap(func (value int) Option[int] {
return Some(value%2)
}).
FlatMap(func (value int) Option[int] {
return Some(value+21)
}).
OrElse(1234)
// 21
option2 := mo.None[int]()
// None
option2.OrElse(1234)
// 1234
option3 := option1.Match(
func(i int) (int, bool) {
// when value is present
return i * 2, true
},
func() (int, bool) {
// when value is absent
return 0, false
},
)
// Some(42)
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.IsAbsent()
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.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
docResult
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.Match()
doc - play.Map()
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])
docEither
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
docEitherX
respresents a value of X possible types. For example, an Either3
value is either T1
, T2
or T3
.
Constructors:
mo.NewEitherXArgY()
doc. Eg:
mo.NewEither3Arg1[A, B, C](A)
mo.NewEither3Arg2[A, B, C](B)
mo.NewEither3Arg3[A, B, C](C)
mo.NewEither4Arg1[A, B, C, D](A)
mo.NewEither4Arg2[A, B, C, D](B)
Methods:
.IsArgX()
doc.ArgX()
doc.MustArgX()
doc.Unpack()
doc.ArgXOrElse()
doc.ArgXOrEmpty()
doc.ForEach()
doc.Match()
doc.MapArgX()
docFuture
represents a value which may or may not currently be available, but will be available at some point, or an exception if that value could not be made available.
Constructors:
mo.NewFuture()
docMethods:
IO
represents a non-deterministic synchronous computation that can cause side effects, yields a value of type R
and never fails.
Constructors:
Methods:
.Run()
docIO
represents a non-deterministic synchronous computation that can cause side effects, yields a value of type R
and can fail.
Constructors:
mo.NewIOEither()
docmo.NewIOEither1()
docmo.NewIOEither2()
docmo.NewIOEither3()
docmo.NewIOEither4()
docmo.NewIOEither5()
docMethods:
.Run()
docTask
represents a non-deterministic asynchronous computation that can cause side effects, yields a value of type R
and never fails.
Constructors:
mo.NewTask()
docmo.NewTask1()
docmo.NewTask2()
docmo.NewTask3()
docmo.NewTask4()
docmo.NewTask5()
docmo.NewTaskFromIO()
docmo.NewTaskFromIO1()
docmo.NewTaskFromIO2()
docmo.NewTaskFromIO3()
docmo.NewTaskFromIO4()
docmo.NewTaskFromIO5()
docMethods:
.Run()
docTaskEither
represents a non-deterministic asynchronous computation that can cause side effects, yields a value of type R
and can fail.
Constructors:
Methods:
State
represents a function (S) -> (A, S)
, where S
is state, A
is result.
Constructors:
Methods:
Foldable represents a type that can be folded into a single value based on its state.
mo.Fold[T, U, R any](f Foldable[T, U], successFunc func(U) R, failureFunc func(T) R) R
doc// @TODO
This library does not use reflect
package. We don't expect overhead.
Don't hesitate ;)
docker-compose run --rm dev
# Install some dev dependencies
make tools
# Run tests
make test
# or
make watch-test
Give a ⭐️ if this project helped you!
Copyright © 2022 Samuel Berthe.
This project is MIT licensed.