Description
๐ฆ samber/mo brings monads and popular FP abstractions to Go projects.
The library uses the recent Go 1.18+ Generics.
mo alternatives and similar packages
Based on the "Functional" category.
Alternatively, view mo alternatives based on common mentions on social networks and blogs.
-
fp-go
Fp-go is a collection of Functional Programming helpers powered by Golang 1.18+ generics. -
gofp
A super simple Lodash like utility library with essential functions that empowers the development in Go -
Goterators
A utility library that supports aggregate & transforms functions Go with generic. Such as filter, map, reduce, find, exist -
underscore
๐ Useful functional programming helpers for Go 1.18 and beyond
Clean code begins in your IDE with SonarLint
Do you think we are missing an alternative of mo or a related project?
Popular Comparisons
README
mo - Monads
๐ฆ samber/mo
brings monads and popular FP abstractions to Go projects. samber/mo
uses the recent Go 1.18+ Generics.
Inspired by:
- Scala
- Rust
- FP-TS
See also:
- samber/lo: A Lodash-style Go library based on Go 1.18+ Generics
- samber/do: A dependency injection toolkit based on Go 1.18+ Generics
Why this name?
I love short name for such utility library. This name is similar to "Monad Go" and no Go package currently uses this name.
๐ก Features
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]
๐ Install
go get github.com/samber/[email protected]
This library is v1 and follows SemVer strictly.
No breaking changes will be made to exported APIs before v2.0.0.
๐ก Quick start
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.
๐ค Documentation and examples
GoDoc: https://godoc.org/github.com/samber/mo
Option[T any]
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
.
Constructors:
Methods:
.IsPresent()
doc.IsAbsent()
doc.Size()
doc.Get()
doc.MustGet()
doc.OrElse()
doc.OrEmpty()
doc.ForEach()
doc.Match()
doc.Map()
doc.MapNone()
doc.FlatMap()
doc
Result[T any]
Result
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]
.
Constructors:
Methods:
.IsOk()
doc.IsError()
doc.Error()
doc.Get()
doc.MustGet()
doc.OrElse()
doc.OrEmpty()
doc.ToEither()
doc.ForEach()
doc.Match()
doc.Map()
doc.MapErr()
doc.FlatMap()
doc
Either[L any, R any]
Either
respresents a value of 2 possible types. An instance of Either
is an instance of either A
or B
.
Constructors:
Methods:
.IsLeft()
doc.IsRight()
doc.Left()
doc.Right()
doc.MustLeft()
doc.MustRight()
doc.LeftOrElse()
doc.RightOrElse()
doc.LeftOrEmpty()
doc.RightOrEmpty()
doc.Swap()
doc.ForEach()
doc.Match()
doc.MapLeft()
doc.MapRight()
doc
EitherX[T1, ..., TX] (With X between 3 and 5)
EitherX
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.ArgXOrElse()
doc.ArgXOrEmpty()
doc.ForEach()
doc.Match()
doc.MapArgX()
doc
Future[T any]
Future
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()
doc
Methods:
IO[T any]
IO
represents a non-deterministic synchronous computation that can cause side effects, yields a value of type R
and never fails.
Constructors:
Methods:
.Run()
doc
IOEither[T any]
IO
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()
doc
Methods:
.Run()
doc
Task[T any]
Task
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()
doc
Methods:
.Run()
doc
TaskEither[T any]
TaskEither
represents a non-deterministic asynchronous computation that can cause side effects, yields a value of type R
and can fail.
Constructors:
Methods:
State[S any, A any]
State
represents a function (S) -> (A, S)
, where S
is state, A
is result.
Constructors:
Methods:
๐ฉ Benchmark
// @TODO
This library does not use reflect
package. We don't expect overhead.
๐ค Contributing
- Ping me on twitter @samuelberthe (DMs, mentions, whatever :))
- Fork the project
- Fix open issues or request new features
Don't hesitate ;)
With Docker
docker-compose run --rm dev
Without Docker
# Install some dev dependencies
make tools
# Run tests
make test
# or
make watch-test
๐ค Authors
- Samuel Berthe
๐ซ Show your support
Give a โญ๏ธ if this project helped you!
๐ License
Copyright ยฉ 2022 Samuel Berthe.
This project is [MIT](./LICENSE) licensed.
*Note that all licence references and agreements mentioned in the mo README section above
are relevant to that project's source code only.