The Principal Dev – Masterclass for Tech Leads

The Principal Dev – Masterclass for Tech LeadsNov 27-28

Join

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:


šŸ’– Support This Project

I’m going all-in on open-source for the coming months.
Help sustain development: Become an individual sponsor or join as a corporate sponsor.


image

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"
)

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:

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:

Sub-package option (transformations and pipes):

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:

Sub-package result (transformations and pipes):

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:

Sub-package either (transformations and pipes):

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:

Sub-packages either3, either4, either5 (transformations and pipes):

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 ;)

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

Join libs.tech

...and unlock some superpowers

GitHub

We won't share your data with anyone else.