mo

package module
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 25, 2022 License: MIT Imports: 2 Imported by: 108

README ΒΆ

mo - Monads

tag GoDoc Build Status Go report codecov

πŸ¦„ 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]
  • Future[T]
  • IO[T]
  • IOEither[T]
  • Task[T]
  • TaskEither[T]
  • State[S, A]

πŸš€ 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.

πŸ’‘ 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:

  • mo.Some() doc
  • mo.None() doc
  • mo.TupleToOption() doc

Methods:

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:

  • mo.Ok() doc
  • mo.Err() doc
  • mo.TupleToResult() doc

Methods:

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:

  • mo.Left() doc
  • mo.Right() doc

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
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:

  • mo.NewIO() doc
  • mo.NewIO1() doc
  • mo.NewIO2() doc
  • mo.NewIO3() doc
  • mo.NewIO4() doc
  • mo.NewIO5() doc

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:

  • mo.NewIOEither() doc
  • mo.NewIOEither1() doc
  • mo.NewIOEither2() doc
  • mo.NewIOEither3() doc
  • mo.NewIOEither4() doc
  • mo.NewIOEither5() doc

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:

  • mo.NewTask() doc
  • mo.NewTask1() doc
  • mo.NewTask2() doc
  • mo.NewTask3() doc
  • mo.NewTask4() doc
  • mo.NewTask5() doc
  • mo.NewTaskFromIO() doc
  • mo.NewTaskFromIO1() doc
  • mo.NewTaskFromIO2() doc
  • mo.NewTaskFromIO3() doc
  • mo.NewTaskFromIO4() doc
  • mo.NewTaskFromIO5() doc

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:

  • mo.NewTaskEither() doc
  • mo.NewTaskEitherFromIOEither() doc

Methods:

State[S any, A any]

State represents a function (S) -> (A, S), where S is state, A is result.

Constructors:

  • mo.NewState() doc
  • mo.ReturnState() doc

Methods:

πŸ›© 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

πŸ‘€ Authors

  • Samuel Berthe

πŸ’« Show your support

Give a ⭐️ if this project helped you!

support us

πŸ“ License

Copyright Β© 2022 Samuel Berthe.

This project is MIT licensed.

Documentation ΒΆ

Index ΒΆ

Examples ΒΆ

Constants ΒΆ

This section is empty.

Variables ΒΆ

This section is empty.

Functions ΒΆ

This section is empty.

Types ΒΆ

type Either ΒΆ

type Either[L any, R any] struct {
	// contains filtered or unexported fields
}

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

func Left ΒΆ

func Left[L any, R any](value L) Either[L, R]

Left builds the left side of the Either struct, as opposed to the Right side.

Example ΒΆ
left := Left[string, int]("hello")
result1 := left.LeftOrElse("world")
result2 := left.RightOrElse(1234)

fmt.Println(result1, result2)
Output:

hello 1234
func Right[L any, R any](value R) Either[L, R]

Right builds the right side of the Either struct, as opposed to the Left side.

Example ΒΆ
right := Right[string, int](42)
result1 := right.LeftOrElse("world")
result2 := right.RightOrElse(1234)

fmt.Println(result1, result2)
Output:

world 42

func (Either[L, R]) ForEach ΒΆ

func (e Either[L, R]) ForEach(leftCb func(L), rightCb func(R))

ForEach executes the given side-effecting function, depending of value is Left or Right.

func (Either[L, R]) IsLeft ΒΆ

func (e Either[L, R]) IsLeft() bool

IsLeft returns true if Either is an instance of Left.

Example (Left) ΒΆ
left := Left[string, int]("hello")
result := left.IsLeft()

fmt.Println(result)
Output:

true
Example (Right) ΒΆ
right := Right[string, int](42)
result := right.IsLeft()

fmt.Println(result)
Output:

false

func (Either[L, R]) IsRight ΒΆ

func (e Either[L, R]) IsRight() bool

IsRight returns true if Either is an instance of Right.

Example (Left) ΒΆ
left := Left[string, int]("hello")
result := left.IsRight()

fmt.Println(result)
Output:

false
Example (Right) ΒΆ
right := Right[string, int](42)
result := right.IsRight()

fmt.Println(result)
Output:

true

func (Either[L, R]) Left ΒΆ

func (e Either[L, R]) Left() (L, bool)

Left returns left value of a Either struct.

Example (Left) ΒΆ
left := Left[string, int]("hello")
result, ok := left.Left()

fmt.Println(result)
fmt.Println(ok)
Output:

hello
true
Example (Right) ΒΆ
right := Right[string, int](42)
result, ok := right.Left()

fmt.Println(result)
fmt.Println(ok)
Output:

false

func (Either[L, R]) LeftOrElse ΒΆ

func (e Either[L, R]) LeftOrElse(fallback L) L

LeftOrElse returns left value of a Either struct or fallback.

Example (Left) ΒΆ
left := Left[string, int]("hello")
result := left.LeftOrElse("world")

fmt.Println(result)
Output:

hello
Example (Right) ΒΆ
right := Right[string, int](42)
result := right.LeftOrElse("world")

fmt.Println(result)
Output:

world

func (Either[L, R]) LeftOrEmpty ΒΆ

func (e Either[L, R]) LeftOrEmpty() L

LeftOrEmpty returns left value of a Either struct or empty value.

Example (Left) ΒΆ
left := Left[string, int]("hello")
result := left.LeftOrEmpty()

fmt.Println(result)
Output:

hello
Example (Right) ΒΆ
right := Right[string, int](42)
result := right.LeftOrEmpty()

fmt.Println(result)
Output:

func (Either[L, R]) MapLeft ΒΆ

func (e Either[L, R]) MapLeft(mapper func(L) Either[L, R]) Either[L, R]

MapLeft executes the given function, if Either is of type Left, and returns result.

Example (Left) ΒΆ
left := Left[string, int]("hello")
result := left.MapLeft(
	func(s string) Either[string, int] {
		return Right[string, int](1234)
	},
)
result1, ok1 := result.Left()
result2, ok2 := result.Right()

fmt.Println(result1)
fmt.Println(ok1)
fmt.Println(result2)
fmt.Println(ok2)
Output:

false
1234
true
Example (Right) ΒΆ
right := Right[string, int](42)
result := right.MapLeft(
	func(s string) Either[string, int] {
		return Left[string, int]("world")
	},
)
result1, ok1 := result.Left()
result2, ok2 := result.Right()

fmt.Println(result1)
fmt.Println(ok1)
fmt.Println(result2)
fmt.Println(ok2)
Output:

false
42
true

func (Either[L, R]) MapRight ΒΆ

func (e Either[L, R]) MapRight(mapper func(R) Either[L, R]) Either[L, R]

MapRight executes the given function, if Either is of type Right, and returns result.

Example (Left) ΒΆ
left := Left[string, int]("hello")
result := left.MapRight(
	func(i int) Either[string, int] {
		return Right[string, int](1234)
	},
)
result1, ok1 := result.Left()
result2, ok2 := result.Right()

fmt.Println(result1)
fmt.Println(ok1)
fmt.Println(result2)
fmt.Println(ok2)
Output:

hello
true
0
false
Example (Right) ΒΆ
right := Right[string, int](42)
result := right.MapRight(
	func(i int) Either[string, int] {
		return Right[string, int](1234)
	},
)
result1, ok1 := result.Left()
result2, ok2 := result.Right()

fmt.Println(result1)
fmt.Println(ok1)
fmt.Println(result2)
fmt.Println(ok2)
Output:

false
1234
true

func (Either[L, R]) Match ΒΆ

func (e Either[L, R]) Match(onLeft func(L) Either[L, R], onRight func(R) Either[L, R]) Either[L, R]

Match executes the given function, depending of value is Left or Right, and returns result.

Example (Left) ΒΆ
left := Left[string, int]("hello")
result := left.Match(
	func(s string) Either[string, int] {
		return Right[string, int](1234)
	},
	func(i int) Either[string, int] {
		return Right[string, int](i * 42)
	},
)
result1, ok1 := result.Left()
result2, ok2 := result.Right()

fmt.Println(result1)
fmt.Println(ok1)
fmt.Println(result2)
fmt.Println(ok2)
Output:

false
1234
true
Example (Right) ΒΆ
right := Right[string, int](42)
result := right.Match(
	func(s string) Either[string, int] {
		return Left[string, int]("world")
	},
	func(i int) Either[string, int] {
		return Left[string, int]("foobar")
	},
)
result1, ok1 := result.Left()
result2, ok2 := result.Right()

fmt.Println(result1)
fmt.Println(ok1)
fmt.Println(result2)
fmt.Println(ok2)
Output:

foobar
true
0
false

func (Either[L, R]) MustLeft ΒΆ

func (e Either[L, R]) MustLeft() L

MustLeft returns left value of a Either struct or panics.

Example (Left) ΒΆ
left := Left[string, int]("hello")
result := left.MustLeft()

fmt.Println(result)
Output:

hello

func (Either[L, R]) MustRight ΒΆ

func (e Either[L, R]) MustRight() R

MustRight returns right value of a Either struct or panics.

Example (Right) ΒΆ
right := Right[string, int](42)
result := right.MustRight()

fmt.Println(result)
Output:

42

func (Either[L, R]) Right ΒΆ

func (e Either[L, R]) Right() (R, bool)

Right returns right value of a Either struct.

Example (Left) ΒΆ
left := Left[string, int]("hello")
result, ok := left.Right()

fmt.Println(result)
fmt.Println(ok)
Output:

0
false
Example (Right) ΒΆ
right := Right[string, int](42)
result, ok := right.Right()

fmt.Println(result)
fmt.Println(ok)
Output:

42
true

func (Either[L, R]) RightOrElse ΒΆ

func (e Either[L, R]) RightOrElse(fallback R) R

RightOrElse returns right value of a Either struct or fallback.

Example (Left) ΒΆ
left := Left[string, int]("hello")
result := left.RightOrElse(1234)

fmt.Println(result)
Output:

1234
Example (Right) ΒΆ
right := Right[string, int](42)
result := right.RightOrElse(1234)

fmt.Println(result)
Output:

42

func (Either[L, R]) RightOrEmpty ΒΆ

func (e Either[L, R]) RightOrEmpty() R

RightOrEmpty returns right value of a Either struct or empty value.

Example (Left) ΒΆ
left := Left[string, int]("hello")
result := left.RightOrEmpty()

fmt.Println(result)
Output:

0
Example (Right) ΒΆ
right := Right[string, int](42)
result := right.RightOrEmpty()

fmt.Println(result)
Output:

42

func (Either[L, R]) Swap ΒΆ

func (e Either[L, R]) Swap() Either[R, L]

Swap returns the left value in Right and vice versa.

Example (Left) ΒΆ
left := Left[string, int]("hello")
right := left.Swap()
result1, ok1 := right.Left()
result2, ok2 := right.Right()

fmt.Println(result1)
fmt.Println(ok1)
fmt.Println(result2)
fmt.Println(ok2)
Output:

0
false
hello
true
Example (Right) ΒΆ
right := Right[string, int](42)
left := right.Swap()
result1, ok1 := left.Left()
result2, ok2 := left.Right()

fmt.Println(result1)
fmt.Println(ok1)
fmt.Println(result2)
fmt.Println(ok2)
// 42
// true
//
// false
Output:

type Future ΒΆ

type Future[T any] struct {
	// contains filtered or unexported fields
}

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.

func NewFuture ΒΆ

func NewFuture[T any](cb func(resolve func(T), reject func(error))) *Future[T]

NewFuture instanciate a new future.

Example (Reject) ΒΆ
value, err := NewFuture(func(resolve func(string), reject func(error)) {
	reject(fmt.Errorf("failure"))
}).Collect()

fmt.Println(value)
fmt.Println(err)
Output:


failure
Example (Resolve) ΒΆ
value, err := NewFuture(func(resolve func(string), reject func(error)) {
	resolve("foobar")
}).Collect()

fmt.Println(value)
fmt.Println(err)
Output:

foobar
<nil>

func (*Future[T]) Cancel ΒΆ

func (f *Future[T]) Cancel()

Cancel cancels the Future chain.

Example (Reject) ΒΆ
NewFuture(func(resolve func(string), reject func(error)) {
	reject(fmt.Errorf("failure"))
}).Cancel()
Output:

Example (Resolve) ΒΆ
NewFuture(func(resolve func(string), reject func(error)) {
	resolve("foobar")
}).Cancel()
Output:

func (*Future[T]) Catch ΒΆ

func (f *Future[T]) Catch(cb func(error) (T, error)) *Future[T]

Catch is called when Future is rejected. It returns a new Future.

Example (Reject) ΒΆ
result := NewFuture(func(resolve func(string), reject func(error)) {
	reject(fmt.Errorf("failure"))
}).Catch(func(err error) (string, error) {
	return "foobar", nil
}).Result()

fmt.Println(result.OrEmpty())
fmt.Println(result.Error())
Output:

foobar
<nil>
Example (Resolve) ΒΆ
result := NewFuture(func(resolve func(string), reject func(error)) {
	resolve("foobar")
}).Catch(func(err error) (string, error) {
	return "baz", nil
}).Result()

fmt.Println(result.OrEmpty())
fmt.Println(result.Error())
Output:

foobar
<nil>

func (*Future[T]) Collect ΒΆ

func (f *Future[T]) Collect() (T, error)

Collect awaits and return result of the Future.

Example (Reject) ΒΆ
value, err := NewFuture(func(resolve func(string), reject func(error)) {
	reject(fmt.Errorf("failure"))
}).Collect()

fmt.Println(value)
fmt.Println(err)
Output:


failure
Example (Resolve) ΒΆ
value, err := NewFuture(func(resolve func(string), reject func(error)) {
	resolve("foobar")
}).Collect()

fmt.Println(value)
fmt.Println(err)
Output:

foobar
<nil>

func (*Future[T]) Either ΒΆ

func (f *Future[T]) Either() Either[error, T]

Result wraps Collect and returns a Result.

func (*Future[T]) Finally ΒΆ

func (f *Future[T]) Finally(cb func(T, error) (T, error)) *Future[T]

Finally is called when Future is processed either resolved or rejected. It returns a new Future.

Example (Reject) ΒΆ
result := NewFuture(func(resolve func(string), reject func(error)) {
	reject(fmt.Errorf("failure"))
}).Finally(func(value string, err error) (string, error) {
	return "foobar", nil
}).Result()

fmt.Println(result.OrEmpty())
fmt.Println(result.Error())
Output:

foobar
<nil>
Example (Resolve) ΒΆ
result := NewFuture(func(resolve func(string), reject func(error)) {
	resolve("foobar")
}).Finally(func(value string, err error) (string, error) {
	return "baz", nil
}).Result()

fmt.Println(result.OrEmpty())
fmt.Println(result.Error())
Output:

baz
<nil>

func (*Future[T]) Result ΒΆ

func (f *Future[T]) Result() Result[T]

Result wraps Collect and returns a Result.

Example (Reject) ΒΆ
result := NewFuture(func(resolve func(string), reject func(error)) {
	reject(fmt.Errorf("failure"))
}).Result()

fmt.Println(result.OrEmpty())
fmt.Println(result.Error())
Output:


failure
Example (Resolve) ΒΆ
result := NewFuture(func(resolve func(string), reject func(error)) {
	resolve("foobar")
}).Result()

fmt.Println(result.OrEmpty())
fmt.Println(result.Error())
Output:

foobar
<nil>

func (*Future[T]) Then ΒΆ

func (f *Future[T]) Then(cb func(T) (T, error)) *Future[T]

Catch is called when Future is resolved. It returns a new Future.

Example (Reject) ΒΆ
result := NewFuture(func(resolve func(string), reject func(error)) {
	reject(fmt.Errorf("failure"))
}).Then(func(s string) (string, error) {
	return "foobar", nil
}).Result()

fmt.Println(result.OrEmpty())
fmt.Println(result.Error())
Output:


failure
Example (Resolve) ΒΆ
result := NewFuture(func(resolve func(string), reject func(error)) {
	resolve("foobar")
}).Then(func(s string) (string, error) {
	return "baz", nil
}).Result()

fmt.Println(result.OrEmpty())
fmt.Println(result.Error())
Output:

baz
<nil>

type IO ΒΆ

type IO[R any] struct {
	// contains filtered or unexported fields
}

IO represents a non-deterministic synchronous computation that can cause side effects, yields a value of type `R` and never fails.

Example ΒΆ
io := NewIO(func() int {
	return time.Now().Year()
})

result1 := io.Run()
result2 := io.Run()
result3 := io.Run()

fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
Output:

2022
2022
2022

func NewIO ΒΆ

func NewIO[R any](f f0[R]) IO[R]

NewIO instanciates a new IO.

func (IO[R]) Run ΒΆ

func (io IO[R]) Run() R

Run execute the non-deterministic synchronous computation, with side effect.

type IO1 ΒΆ

type IO1[R any, A any] struct {
	// contains filtered or unexported fields
}

IO1 represents a non-deterministic synchronous computation that can cause side effects, yields a value of type `R` and never fails.

func NewIO1 ΒΆ

func NewIO1[R any, A any](f f1[R, A]) IO1[R, A]

NewIO1 instanciates a new IO1.

func (IO1[R, A]) Run ΒΆ

func (io IO1[R, A]) Run(a A) R

Run execute the non-deterministic synchronous computation, with side effect.

type IO2 ΒΆ

type IO2[R any, A any, B any] struct {
	// contains filtered or unexported fields
}

IO2 represents a non-deterministic synchronous computation that can cause side effects, yields a value of type `R` and never fails.

func NewIO2 ΒΆ

func NewIO2[R any, A any, B any](f f2[R, A, B]) IO2[R, A, B]

NewIO2 instanciates a new IO2.

func (IO2[R, A, B]) Run ΒΆ

func (io IO2[R, A, B]) Run(a A, b B) R

Run execute the non-deterministic synchronous computation, with side effect.

type IO3 ΒΆ

type IO3[R any, A any, B any, C any] struct {
	// contains filtered or unexported fields
}

IO3 represents a non-deterministic synchronous computation that can cause side effects, yields a value of type `R` and never fails.

func NewIO3 ΒΆ

func NewIO3[R any, A any, B any, C any](f f3[R, A, B, C]) IO3[R, A, B, C]

NewIO3 instanciates a new IO3.

func (IO3[R, A, B, C]) Run ΒΆ

func (io IO3[R, A, B, C]) Run(a A, b B, c C) R

Run execute the non-deterministic synchronous computation, with side effect.

type IO4 ΒΆ

type IO4[R any, A any, B any, C any, D any] struct {
	// contains filtered or unexported fields
}

IO4 represents a non-deterministic synchronous computation that can cause side effects, yields a value of type `R` and never fails.

func NewIO4 ΒΆ

func NewIO4[R any, A any, B any, C any, D any](f f4[R, A, B, C, D]) IO4[R, A, B, C, D]

NewIO4 instanciates a new IO4.

func (IO4[R, A, B, C, D]) Run ΒΆ

func (io IO4[R, A, B, C, D]) Run(a A, b B, c C, d D) R

Run execute the non-deterministic synchronous computation, with side effect.

type IO5 ΒΆ

type IO5[R any, A any, B any, C any, D any, E any] struct {
	// contains filtered or unexported fields
}

IO5 represents a non-deterministic synchronous computation that can cause side effects, yields a value of type `R` and never fails.

func NewIO5 ΒΆ

func NewIO5[R any, A any, B any, C any, D any, E any](f f5[R, A, B, C, D, E]) IO5[R, A, B, C, D, E]

NewIO5 instanciates a new IO5.

func (IO5[R, A, B, C, D, E]) Run ΒΆ

func (io IO5[R, A, B, C, D, E]) Run(a A, b B, c C, d D, e E) R

Run execute the non-deterministic synchronous computation, with side effect.

type IOEither ΒΆ

type IOEither[R any] struct {
	// contains filtered or unexported fields
}

IO represents a non-deterministic synchronous computation that can cause side effects, yields a value of type `R` and can fail.

func NewIOEither ΒΆ

func NewIOEither[R any](f fe0[R]) IOEither[R]

NewIOEither instanciates a new IO.

func (IOEither[R]) Run ΒΆ

func (io IOEither[R]) Run() Either[error, R]

Run execute the non-deterministic synchronous computation, with side effect.

type IOEither1 ΒΆ

type IOEither1[R any, A any] struct {
	// contains filtered or unexported fields
}

IO1 represents a non-deterministic synchronous computation that can cause side effects, yields a value of type `R` and can fail.

Example ΒΆ
io := NewIOEither1(func(path string) (bool, error) {
	_, err := os.Stat(path)

	if errors.Is(err, os.ErrNotExist) {
		return false, nil
	} else if err != nil {
		// other errors
		return false, err
	}

	return true, nil
})

either1 := io.Run("./io_either.go")
either2 := io.Run("./foo_bar.go")

exist1, _ := either1.Right()
exist2, _ := either2.Right()

fmt.Println(exist1)
fmt.Println(exist2)
Output:

true
false

func NewIOEither1 ΒΆ

func NewIOEither1[R any, A any](f fe1[R, A]) IOEither1[R, A]

NewIOEither1 instanciates a new IO1.

func (IOEither1[R, A]) Run ΒΆ

func (io IOEither1[R, A]) Run(a A) Either[error, R]

Run execute the non-deterministic synchronous computation, with side effect.

type IOEither2 ΒΆ

type IOEither2[R any, A any, B any] struct {
	// contains filtered or unexported fields
}

IO2 represents a non-deterministic synchronous computation that can cause side effects, yields a value of type `R` and can fail.

func NewIOEither2 ΒΆ

func NewIOEither2[R any, A any, B any](f fe2[R, A, B]) IOEither2[R, A, B]

NewIOEither2 instanciates a new IO2.

func (IOEither2[R, A, B]) Run ΒΆ

func (io IOEither2[R, A, B]) Run(a A, b B) Either[error, R]

Run execute the non-deterministic synchronous computation, with side effect.

type IOEither3 ΒΆ

type IOEither3[R any, A any, B any, C any] struct {
	// contains filtered or unexported fields
}

IO3 represents a non-deterministic synchronous computation that can cause side effects, yields a value of type `R` and can fail.

func NewIOEither3 ΒΆ

func NewIOEither3[R any, A any, B any, C any](f fe3[R, A, B, C]) IOEither3[R, A, B, C]

NewIOEither3 instanciates a new IO3.

func (IOEither3[R, A, B, C]) Run ΒΆ

func (io IOEither3[R, A, B, C]) Run(a A, b B, c C) Either[error, R]

Run execute the non-deterministic synchronous computation, with side effect.

type IOEither4 ΒΆ

type IOEither4[R any, A any, B any, C any, D any] struct {
	// contains filtered or unexported fields
}

IO4 represents a non-deterministic synchronous computation that can cause side effects, yields a value of type `R` and can fail.

func NewIOEither4 ΒΆ

func NewIOEither4[R any, A any, B any, C any, D any](f fe4[R, A, B, C, D]) IOEither4[R, A, B, C, D]

NewIOEither4 instanciates a new IO4.

func (IOEither4[R, A, B, C, D]) Run ΒΆ

func (io IOEither4[R, A, B, C, D]) Run(a A, b B, c C, d D) Either[error, R]

Run execute the non-deterministic synchronous computation, with side effect.

type IOEither5 ΒΆ

type IOEither5[R any, A any, B any, C any, D any, E any] struct {
	// contains filtered or unexported fields
}

IO5 represents a non-deterministic synchronous computation that can cause side effects, yields a value of type `R` and can fail.

func NewIOEither5 ΒΆ

func NewIOEither5[R any, A any, B any, C any, D any, E any](f fe5[R, A, B, C, D, E]) IOEither5[R, A, B, C, D, E]

NewIOEither5 instanciates a new IO5.

func (IOEither5[R, A, B, C, D, E]) Run ΒΆ

func (io IOEither5[R, A, B, C, D, E]) Run(a A, b B, c C, d D, e E) Either[error, R]

Run execute the non-deterministic synchronous computation, with side effect.

type Option ΒΆ

type Option[T any] struct {
	// contains filtered or unexported fields
}

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.

Example (None) ΒΆ
none := None[int]()
result := none.OrElse(1234)

fmt.Println(result)
Output:

1234
Example (Some) ΒΆ
some := Some(42)
result := some.OrElse(1234)

fmt.Println(result)
Output:

42

func None ΒΆ

func None[T any]() Option[T]

None builds an Option when value is absent.

Example ΒΆ
none := None[int]()
result := none.OrElse(1234)

fmt.Println(result)
Output:

1234

func Some ΒΆ

func Some[T any](value T) Option[T]

Some builds an Option when value is present.

Example ΒΆ
some := Some(42)
result := some.OrElse(1234)

fmt.Println(result)
Output:

42

func TupleToOption ΒΆ

func TupleToOption[T any](value T, ok bool) Option[T]
Example ΒΆ
m := map[string]int{
	"foo": 21,
	"bar": 42,
	"baz": 84,
}

value, ok := m["hello world"]

none := TupleToOption(value, ok)
result := none.OrElse(1234)

fmt.Println(result)
Output:

1234

func (Option[T]) FlatMap ΒΆ

func (o Option[T]) FlatMap(mapper func(value T) Option[T]) Option[T]

FlatMap executes the mapper function if value is present or returns None if absent.

Example (None) ΒΆ
none := None[int]()
result := none.FlatMap(func(i int) Option[int] {
	return Some(21)
})

fmt.Println(result.IsPresent(), result.OrEmpty())
Output:

false 0
Example (Some) ΒΆ
some := Some(42)
result := some.FlatMap(func(i int) Option[int] {
	return Some(21)
})

fmt.Println(result.IsPresent(), result.OrEmpty())
Output:

true 21

func (Option[T]) ForEach ΒΆ

func (o Option[T]) ForEach(onValue func(value T))

ForEach executes the given side-effecting function of value is present.

func (Option[T]) Get ΒΆ

func (o Option[T]) Get() (T, bool)

Get returns value and presence.

Example (None) ΒΆ
none := None[int]()
result, ok := none.Get()

fmt.Println(result)
fmt.Println(ok)
Output:

0
false
Example (Some) ΒΆ
some := Some(42)
result, ok := some.Get()

fmt.Println(result)
fmt.Println(ok)
Output:

42
true

func (Option[T]) IsAbsent ΒΆ

func (o Option[T]) IsAbsent() bool

IsAbsent returns true when value is present.

Example (None) ΒΆ
none := None[int]()
result := none.IsAbsent()

fmt.Println(result)
Output:

true
Example (Some) ΒΆ
some := Some(42)
result := some.IsAbsent()

fmt.Println(result)
Output:

false

func (Option[T]) IsPresent ΒΆ

func (o Option[T]) IsPresent() bool

IsPresent returns true when value is absent.

Example (None) ΒΆ
none := None[int]()
result := none.IsPresent()

fmt.Println(result)
Output:

false
Example (Some) ΒΆ
some := Some(42)
result := some.IsPresent()

fmt.Println(result)
Output:

true

func (Option[T]) Map ΒΆ

func (o Option[T]) Map(mapper func(value T) (T, bool)) Option[T]

Map executes the mapper function if value is present or returns None if absent.

Example (None) ΒΆ
none := None[int]()
result := none.Map(func(i int) (int, bool) {
	return 1234, true
})

fmt.Println(result.IsPresent(), result.OrEmpty())
Output:

false 0
Example (Some) ΒΆ
some := Some(42)
result := some.Map(func(i int) (int, bool) {
	return 1234, true
})

fmt.Println(result.IsPresent(), result.OrEmpty())
Output:

true 1234

func (Option[T]) MapNone ΒΆ

func (o Option[T]) MapNone(mapper func() (T, bool)) Option[T]

MapNone executes the mapper function if value is absent or returns Option.

Example (None) ΒΆ
none := None[int]()
result := none.MapNone(func() (int, bool) {
	return 1234, true
})

fmt.Println(result.IsPresent(), result.OrEmpty())
Output:

true 1234
Example (Some) ΒΆ
some := Some(42)
result := some.MapNone(func() (int, bool) {
	return 1234, true
})

fmt.Println(result.IsPresent(), result.OrEmpty())
Output:

true 42

func (Option[T]) Match ΒΆ

func (o Option[T]) Match(onValue func(value T) (T, bool), onNone func() (T, bool)) Option[T]

Match executes the first function if value is present and second function if absent. It returns a new Option.

Example (None) ΒΆ
none := None[int]()
result := none.Match(
	func(i int) (int, bool) {
		return 0, false
	},
	func() (int, bool) {
		return 2, true
	},
)

fmt.Println(result.IsPresent(), result.OrEmpty())
Output:

true 2
Example (Some) ΒΆ
some := Some(42)
result := some.Match(
	func(i int) (int, bool) {
		return 0, false
	},
	func() (int, bool) {
		return 2, true
	},
)

fmt.Println(result.IsPresent(), result.OrEmpty())
Output:

false 0

func (Option[T]) MustGet ΒΆ

func (o Option[T]) MustGet() T

MustGet returns value if present or panics instead.

Example (Some) ΒΆ
some := Some(42)
result := some.MustGet()

fmt.Println(result)
Output:

42

func (Option[T]) OrElse ΒΆ

func (o Option[T]) OrElse(fallback T) T

OrElse returns value if present or default value.

Example (None) ΒΆ
none := None[int]()
result := none.OrElse(1234)

fmt.Println(result)
Output:

1234
Example (Some) ΒΆ
some := Some(42)
result := some.OrElse(1234)

fmt.Println(result)
Output:

42

func (Option[T]) OrEmpty ΒΆ

func (o Option[T]) OrEmpty() T

OrEmpty returns value if present or empty value.

Example (None) ΒΆ
none := None[int]()
result := none.OrEmpty()

fmt.Println(result)
Output:

0
Example (Some) ΒΆ
some := Some(42)
result := some.OrEmpty()

fmt.Println(result)
Output:

42

func (Option[T]) Size ΒΆ

func (o Option[T]) Size() int

Size returns 1 when value is present or 0 instead.

Example (None) ΒΆ
none := None[int]()
result := none.Size()

fmt.Println(result)
Output:

0
Example (Some) ΒΆ
some := Some(42)
result := some.Size()

fmt.Println(result)
Output:

1

type Result ΒΆ

type Result[T any] struct {
	// contains filtered or unexported fields
}

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

Example (Err) ΒΆ
ko := Err[int](err)
result := ko.OrElse(1234)
_err := ko.Error()

fmt.Println(result, _err)
Output:

1234 error
Example (Ok) ΒΆ
ok := Ok(42)
result := ok.OrElse(1234)
_err := ok.Error()

fmt.Println(result, _err)
Output:

42 <nil>

func Err ΒΆ

func Err[T any](err error) Result[T]

Err builds a Result when value is invalid.

Example ΒΆ
ko := Err[int](err)
result := ko.OrElse(1234)
_err := ko.Error()

fmt.Println(result, _err)
Output:

1234 error

func Ok ΒΆ

func Ok[T any](value T) Result[T]

Ok builds a Result when value is valid.

Example ΒΆ
ok := Ok(42)
result := ok.OrElse(1234)
_err := ok.Error()

fmt.Println(result, _err)
Output:

42 <nil>

func TupleToResult ΒΆ

func TupleToResult[T any](value T, err error) Result[T]

TupleToResult convert a pair of T and error into a Result.

Example ΒΆ
randomFunc := func() (int, error) {
	return 42, err
}

value, _err := randomFunc()

none := TupleToResult(value, _err)
result := none.OrElse(1234)

fmt.Println(result)
Output:

1234

func (Result[T]) Error ΒΆ

func (r Result[T]) Error() error

Error returns error when value is invalid or nil.

Example (Err) ΒΆ
ko := Err[int](err)
result := ko.Error()

fmt.Println(result)
Output:

error
Example (Ok) ΒΆ
ok := Ok(42)
result := ok.Error()

fmt.Println(result)
Output:

<nil>

func (Result[T]) FlatMap ΒΆ

func (r Result[T]) FlatMap(mapper func(value T) Result[T]) Result[T]

FlatMap executes the mapper function if Result is valid. It returns a new Result.

Example (Err) ΒΆ
ko := Err[int](err)
result := ko.FlatMap(
	func(i int) Result[int] {
		return Ok(1234)
	},
)

fmt.Println(result.IsError(), result.OrEmpty(), result.Error())
Output:

true 0 error
Example (Ok) ΒΆ
ok := Ok(42)
result := ok.FlatMap(
	func(i int) Result[int] {
		return Ok(1234)
	},
)

fmt.Println(result.IsError(), result.OrEmpty(), result.Error())
Output:

false 1234 <nil>

func (Result[T]) ForEach ΒΆ

func (r Result[T]) ForEach(mapper func(value T))

ForEach executes the given side-effecting function if Result is valid.

func (Result[T]) Get ΒΆ

func (r Result[T]) Get() (T, error)

MustGet returns value and error.

Example (Err) ΒΆ
ko := Err[int](err)
result, err := ko.Get()

fmt.Println(result)
fmt.Println(err)
Output:

0
error
Example (Ok) ΒΆ
ok := Ok(42)
result, err := ok.Get()

fmt.Println(result)
fmt.Println(err)
Output:

42
<nil>

func (Result[T]) IsError ΒΆ

func (r Result[T]) IsError() bool

IsError returns true when value is invalid.

Example (Err) ΒΆ
ko := Err[int](err)
result := ko.IsError()

fmt.Println(result)
Output:

true
Example (Ok) ΒΆ
ok := Ok(42)
result := ok.IsError()

fmt.Println(result)
Output:

false

func (Result[T]) IsOk ΒΆ

func (r Result[T]) IsOk() bool

IsOk returns true when value is valid.

Example (Err) ΒΆ
ko := Err[int](err)
result := ko.IsOk()

fmt.Println(result)
Output:

false
Example (Ok) ΒΆ
ok := Ok(42)
result := ok.IsOk()

fmt.Println(result)
Output:

true

func (Result[T]) Map ΒΆ

func (r Result[T]) Map(mapper func(value T) (T, error)) Result[T]

Map executes the mapper function if Result is valid. It returns a new Result.

Example (Err) ΒΆ
ko := Err[int](err)
result := ko.Map(
	func(i int) (int, error) {
		return i * 2, nil
	},
)

fmt.Println(result.IsError(), result.OrEmpty(), result.Error())
Output:

true 0 error
Example (Ok) ΒΆ
ok := Ok(42)
result := ok.Map(
	func(i int) (int, error) {
		return i * 2, nil
	},
)

fmt.Println(result.IsError(), result.OrEmpty(), result.Error())
Output:

false 84 <nil>

func (Result[T]) MapErr ΒΆ

func (r Result[T]) MapErr(mapper func(error) (T, error)) Result[T]

MapErr executes the mapper function if Result is invalid. It returns a new Result.

Example (Err) ΒΆ
ko := Err[int](err)
result := ko.MapErr(
	func(_err error) (int, error) {
		return 1234, nil
	},
)

fmt.Println(result.IsError(), result.OrEmpty(), result.Error())
Output:

false 1234 <nil>
Example (Ok) ΒΆ
ok := Ok(42)
result := ok.MapErr(
	func(_err error) (int, error) {
		return 1234, nil
	},
)

fmt.Println(result.IsError(), result.OrEmpty(), result.Error())
Output:

false 42 <nil>

func (Result[T]) Match ΒΆ

func (r Result[T]) Match(onSuccess func(value T) (T, error), onError func(err error) (T, error)) Result[T]

Match executes the first function if Result is valid and second function if invalid. It returns a new Result.

Example (Err) ΒΆ
ko := Err[int](err)
result := ko.Match(
	func(i int) (int, error) {
		return i * 2, nil
	},
	func(err error) (int, error) {
		return 21, nil
	},
)

fmt.Println(result.IsError(), result.OrEmpty(), result.Error())
Output:

false 21 <nil>
Example (Ok) ΒΆ
ok := Ok(42)
result := ok.Match(
	func(i int) (int, error) {
		return i * 2, nil
	},
	func(err error) (int, error) {
		return 21, nil
	},
)

fmt.Println(result.IsError(), result.OrEmpty(), result.Error())
Output:

false 84 <nil>

func (Result[T]) MustGet ΒΆ

func (r Result[T]) MustGet() T

MustGet returns value when Result is valid or panics.

Example (Ok) ΒΆ
ok := Ok(42)
result := ok.MustGet()

fmt.Println(result)
Output:

42

func (Result[T]) OrElse ΒΆ

func (r Result[T]) OrElse(fallback T) T

OrElse returns value when Result is valid or default value.

Example (Err) ΒΆ
ko := Err[int](err)
result := ko.OrElse(1234)

fmt.Println(result)
Output:

1234
Example (Ok) ΒΆ
ok := Ok(42)
result := ok.OrElse(1234)

fmt.Println(result)
Output:

42

func (Result[T]) OrEmpty ΒΆ

func (r Result[T]) OrEmpty() T

OrEmpty returns value when Result is valid or empty value.

Example (Err) ΒΆ
ko := Err[int](err)
result := ko.OrEmpty()

fmt.Println(result)
Output:

0
Example (Ok) ΒΆ
ok := Ok(42)
result := ok.OrEmpty()

fmt.Println(result)
Output:

42

func (Result[T]) ToEither ΒΆ

func (r Result[T]) ToEither() Either[error, T]

ToEither transforms a Result into an Either type.

Example (Err) ΒΆ
ko := Err[int](err)
either := ko.ToEither()

err, isLeft := either.Left()
value, isRight := either.Right()

fmt.Println(isLeft, isRight)
fmt.Println(err)
fmt.Println(value)
Output:

true false
error
0
Example (Ok) ΒΆ
ok := Ok(42)
either := ok.ToEither()

err, isLeft := either.Left()
value, isRight := either.Right()

fmt.Println(isLeft, isRight)
fmt.Println(err)
fmt.Println(value)
Output:

false true
<nil>
42

type State ΒΆ

type State[S any, A any] struct {
	// contains filtered or unexported fields
}

State represents a function `(S) -> (A, S)`, where `S` is state, `A` is result.

func NewState ΒΆ

func NewState[S any, A any](f func(state S) (A, S)) State[S, A]

func ReturnState ΒΆ

func ReturnState[S any, A any](x A) State[S, A]

func (State[S, A]) Get ΒΆ

func (s State[S, A]) Get() State[S, S]

Get returns the current state.

func (State[S, A]) Modify ΒΆ

func (s State[S, A]) Modify(f func(state S) S) State[S, A]

Modify the state by applying a function to the current state.

func (State[S, A]) Put ΒΆ

func (s State[S, A]) Put(state S) State[S, A]

Put set the state.

func (State[S, A]) Run ΒΆ

func (s State[S, A]) Run(state S) (A, S)

Run executes a computation in the State monad.

type Task ΒΆ

type Task[R any] struct {
	// contains filtered or unexported fields
}

Task represents a non-deterministic asynchronous computation that can cause side effects, yields a value of type `R` and never fails.

Example ΒΆ
task := NewTask(func() *Future[int] {
	return NewFuture(func(resolve func(int), reject func(error)) {
		resolve(time.Now().Year())
	})
})

// returns a future
future := task.Run()

// a Task never fail
result, _ := future.Collect()

fmt.Println(result)
Output:

2022

func NewTask ΒΆ

func NewTask[R any](f ff0[R]) Task[R]

NewTask instanciates a new Task.

func NewTaskFromIO ΒΆ

func NewTaskFromIO[R any](io IO[R]) Task[R]

NewTaskFromIO instanciates a new Task from an existing IO.

func (Task[R]) Run ΒΆ

func (t Task[R]) Run() *Future[R]

Run execute the non-deterministic asynchronous computation, with side effect.

type Task1 ΒΆ

type Task1[R any, A any] struct {
	// contains filtered or unexported fields
}

Task1 represents a non-deterministic asynchronous computation that can cause side effects, yields a value of type `R` and never fails.

func NewTask1 ΒΆ

func NewTask1[R any, A any](f ff1[R, A]) Task1[R, A]

NewTask1 instanciates a new Task1.

func NewTaskFromIO1 ΒΆ

func NewTaskFromIO1[R any, A any](io IO1[R, A]) Task1[R, A]

NewTaskFromIO1 instanciates a new Task1 from an existing IO1.

func (Task1[R, A]) Run ΒΆ

func (t Task1[R, A]) Run(a A) *Future[R]

Run execute the non-deterministic asynchronous computation, with side effect.

type Task2 ΒΆ

type Task2[R any, A any, B any] struct {
	// contains filtered or unexported fields
}

Task2 represents a non-deterministic asynchronous computation that can cause side effects, yields a value of type `R` and never fails.

func NewTask2 ΒΆ

func NewTask2[R any, A any, B any](f ff2[R, A, B]) Task2[R, A, B]

NewTask2 instanciates a new Task2.

func NewTaskFromIO2 ΒΆ

func NewTaskFromIO2[R any, A any, B any](io IO2[R, A, B]) Task2[R, A, B]

NewTaskFromIO2 instanciates a new Task2 from an existing IO2.

func (Task2[R, A, B]) Run ΒΆ

func (t Task2[R, A, B]) Run(a A, b B) *Future[R]

Run execute the non-deterministic asynchronous computation, with side effect.

type Task3 ΒΆ

type Task3[R any, A any, B any, C any] struct {
	// contains filtered or unexported fields
}

Task3 represents a non-deterministic asynchronous computation that can cause side effects, yields a value of type `R` and never fails.

func NewTask3 ΒΆ

func NewTask3[R any, A any, B any, C any](f ff3[R, A, B, C]) Task3[R, A, B, C]

NewTask3 instanciates a new Task3.

func NewTaskFromIO3 ΒΆ

func NewTaskFromIO3[R any, A any, B any, C any](io IO3[R, A, B, C]) Task3[R, A, B, C]

NewTaskFromIO3 instanciates a new Task3 from an existing IO3.

func (Task3[R, A, B, C]) Run ΒΆ

func (t Task3[R, A, B, C]) Run(a A, b B, c C) *Future[R]

Run execute the non-deterministic asynchronous computation, with side effect.

type Task4 ΒΆ

type Task4[R any, A any, B any, C any, D any] struct {
	// contains filtered or unexported fields
}

Task4 represents a non-deterministic asynchronous computation that can cause side effects, yields a value of type `R` and never fails.

func NewTask4 ΒΆ

func NewTask4[R any, A any, B any, C any, D any](f ff4[R, A, B, C, D]) Task4[R, A, B, C, D]

NewTask4 instanciates a new Task4.

func NewTaskFromIO4 ΒΆ

func NewTaskFromIO4[R any, A any, B any, C any, D any](io IO4[R, A, B, C, D]) Task4[R, A, B, C, D]

NewTaskFromIO4 instanciates a new Task4 from an existing IO4.

func (Task4[R, A, B, C, D]) Run ΒΆ

func (t Task4[R, A, B, C, D]) Run(a A, b B, c C, d D) *Future[R]

Run execute the non-deterministic asynchronous computation, with side effect.

type Task5 ΒΆ

type Task5[R any, A any, B any, C any, D any, E any] struct {
	// contains filtered or unexported fields
}

Task5 represents a non-deterministic asynchronous computation that can cause side effects, yields a value of type `R` and never fails.

func NewTask5 ΒΆ

func NewTask5[R any, A any, B any, C any, D any, E any](f ff5[R, A, B, C, D, E]) Task5[R, A, B, C, D, E]

NewTask5 instanciates a new Task5.

func NewTaskFromIO5 ΒΆ

func NewTaskFromIO5[R any, A any, B any, C any, D any, E any](io IO5[R, A, B, C, D, E]) Task5[R, A, B, C, D, E]

NewTaskFromIO5 instanciates a new Task5 from an existing IO5.

func (Task5[R, A, B, C, D, E]) Run ΒΆ

func (t Task5[R, A, B, C, D, E]) Run(a A, b B, c C, d D, e E) *Future[R]

Run execute the non-deterministic asynchronous computation, with side effect.

type TaskEither ΒΆ

type TaskEither[R any] struct {
	Task[R]
}

TaskEither represents a non-deterministic asynchronous computation that can cause side effects, yields a value of type `R` and can fail.

func NewTaskEither ΒΆ

func NewTaskEither[R any](f ff0[R]) TaskEither[R]

NewTaskEither instanciates a new TaskEither.

func NewTaskEitherFromIO ΒΆ

func NewTaskEitherFromIO[R any](io IO[R]) TaskEither[R]

NewTaskEitherFromIO instanciates a new TaskEither from an existing IO.

func (TaskEither[R]) Match ΒΆ

func (t TaskEither[R]) Match(onLeft func(error) Either[error, R], onRight func(R) Either[error, R]) Either[error, R]

Match executes the first function if task succeeded and second function if task failed. It returns a new Option.

func (TaskEither[R]) OrElse ΒΆ

func (t TaskEither[R]) OrElse(fallback R) R

OrElse returns value if task succeeded or default value.

func (TaskEither[R]) ToEither ΒΆ

func (t TaskEither[R]) ToEither() Either[error, R]

ToTask converts TaskEither to Task

func (TaskEither[R]) ToTask ΒΆ

func (t TaskEither[R]) ToTask(fallback R) Task[R]

ToTask converts TaskEither to Task

func (TaskEither[R]) TryCatch ΒΆ

func (t TaskEither[R]) TryCatch(onLeft func(error) Either[error, R], onRight func(R) Either[error, R]) Either[error, R]

TryCatch is an alias to Match

Directories ΒΆ

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL