Home

Awesome

mo - Monads

tag Go Version GoDoc Build Status Go report Coverage License

🦄 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.

💡 Features

We currently support the following data types:

🚀 Install

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.

💡 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.

Tips for lazy developers

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. 😁 💩

🤠 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.

Implements:

Constructors:

Methods:

Other:

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].

Implements:

Constructors:

Methods:

Other:

Either[L any, R any]

Either represents a value of 2 possible types. An instance of Either is an instance of either A or B.

Implements:

Constructors:

Methods:

Other:

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:

Methods:

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:

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:

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:

Methods:

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:

Methods:

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:

Foldable[T, U]

Foldable represents a type that can be folded into a single value based on its state.

🛩 Benchmark

// @TODO

This library does not use reflect package. We don't expect overhead.

🤝 Contributing

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

👤 Contributors

Contributors

💫 Show your support

Give a ⭐️ if this project helped you!

GitHub Sponsors

📝 License

Copyright © 2022 Samuel Berthe.

This project is MIT licensed.