maybe

package
v2.8.2 Latest Latest
Warning

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

Go to latest
Published: Feb 17, 2023 License: MIT Imports: 1 Imported by: 0

Documentation

Overview

Package maybe implements a M{value, ok} "sum type" that has a value only when ok is true.

Note that in many cases, it is more idiomatic for a function to return a naked (value, ok). Use WrapFunc to convert such a function to return a M maybe type.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Applicator added in v2.2.0

func Applicator[X any, Y any](
	f M[func(x X) Y],
) func(x X) M[Y]

Applicator turns function "M[f: X => Y]" into "f: X => M[Y]".

Example
package main

import (
	"fmt"

	"github.com/tawesoft/golib/v2/fun/maybe"
	"github.com/tawesoft/golib/v2/fun/partial"
)

func main() {
	friend := func(a string, b string) string {
		return fmt.Sprintf("%s is friends with %s", a, b)
	}
	friendPartial := partial.Left2(friend) // f(a) => f(b) => string
	friendM := maybe.Map(friendPartial)

	fmt.Printf("func friend: %T\n", friend)
	fmt.Printf("func friendPartial: %T\n", friendPartial)
	fmt.Printf("func friendM: %T\n", friendM)

	alice := maybe.Some("Alice")
	bob := maybe.Some("Bob")
	charlie := maybe.Some("Charlie")
	nobody := maybe.Nothing[string]()

	friendsWithAlice := maybe.FlatMap(maybe.Applicator(friendM(alice)))
	friendsWithBob := maybe.FlatMap(maybe.Applicator(friendM(bob)))
	friendsWithNobody := maybe.FlatMap(maybe.Applicator(friendM(nobody)))

	fmt.Printf("func friendsWithAlice: %T\n\n", friendsWithAlice)

	fmt.Println(friendsWithAlice(bob).Must())
	fmt.Println(friendsWithBob(charlie).Must())
	friendsWithNobody(alice).MustNot()
	friendsWithAlice(nobody).MustNot()

}
Output:

func friend: func(string, string) string
func friendPartial: func(string) func(string) string
func friendM: func(maybe.M[string]) maybe.M[func(string) string]
func friendsWithAlice: func(maybe.M[string]) maybe.M[string]

Alice is friends with Bob
Bob is friends with Charlie

func Compose added in v2.2.0

func Compose[X any, Y any, Z any](
	xy func(M[X]) M[Y],
	yz func(M[Y]) M[Z],
) func(M[X]) M[Z]

Compose takes two functions of the form "xy: M[X] => M[Y]" and "yz: M[Y] => M[Z]" and returns a function "xz(M[X]) => M[Z]".

func FlatMap

func FlatMap[X any, Y any](
	f func(x X) M[Y],
) func(x2 M[X]) M[Y]

FlatMap turns function "f: X => M[Y]" into "f: M(X) => M[Y]".

func Lift

func Lift[X any, Y any](
	f func(x X) Y,
) func(x X) M[Y]

Lift converts a function of the form "f: X => Y" to the form "f: X => M[Y]" where M[Y] == Some(y).

func Map

func Map[X any, Y any](
	f func(x X) Y,
) func(x2 M[X]) M[Y]

Map turns function "f: X => Y" into "f: M(X) => M[Y]".

func UnwrapFunc

func UnwrapFunc[X any, Y any](
	f func(x X) M[Y],
) func(x X) (Y, bool)

UnwrapFunc converts a function of the form "f: X => M[Y]" to the form "f: X => ([Y], ok bool)".

func WrapFunc

func WrapFunc[X any, Y any](
	f func(x X) (Y, bool),
) func(x X) M[Y]

WrapFunc converts a function of the form "f: X => (Y, ok bool)" to the form "f: X => M[X].

func WrapFunc2 added in v2.7.0

func WrapFunc2[A any, B any, C any](
	f func(a A, b B) (C, bool),
) func(a A, b B) M[C]

WrapFunc2 converts a function of the form "f(A, B) => (C, ok bool)" to the form "f(A, B) => M[C].

func WrapFunc3 added in v2.7.0

func WrapFunc3[A any, B any, C any, D any](
	f func(a A, b B, c C) (D, bool),
) func(a A, b B, c C) M[D]

WrapFunc3 converts a function of the form "f(A, B, C) => (D, ok bool)" to the form "f(A, B, C) => M[D].

func WrapFunc4 added in v2.7.0

func WrapFunc4[A any, B any, C any, D any, E any](
	f func(a A, b B, c C, d D) (E, bool),
) func(a A, b B, c C, d D) M[E]

WrapFunc4 converts a function of the form "f(A, B, C, D) => (E, ok bool)" to the form "f(A, B, C, D) => M[E].

Types

type M added in v2.2.0

type M[V any] struct {
	Value V
	Ok    bool
}

M is a (value, ok) "sum type" that has a value only when ok is true.

Example
package main

import (
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/tawesoft/golib/v2/fun/maybe"

	"github.com/tawesoft/golib/v2/fun/slices"
)

func main() {
	maybeOpen := func(x string) maybe.M[*os.File] {
		f, err := os.Open(x)
		if err != nil {
			return maybe.Nothing[*os.File]()
		}
		return maybe.Some(f)
	}

	closer := func(f *os.File) error {
		fmt.Printf("Closing %s\n", f.Name())
		return f.Close()
	}

	paths := []string{
		"testdata/example1.txt",
		"testdata/example2.txt",
		"testdata/example3.txt",
	}

	handles := slices.Map(maybeOpen, paths)
	defer slices.Map(maybe.Map(closer), handles)

	maybeRead := func(x *os.File) maybe.M[string] {
		content, err := io.ReadAll(x)
		if err != nil {
			return maybe.Nothing[string]()
		}
		return maybe.Some(string(content))
	}

	contents := slices.Map(maybe.FlatMap(maybeRead), handles)

	for i, x := range contents {
		if x.Ok {
			fmt.Println(strings.TrimSpace(x.Value))
		} else {
			fmt.Printf("Could not read from file %d\n", i+1)
		}
	}

}
Output:

This is the first file!
Could not read from file 2
This is the third file!
Closing testdata/example1.txt
Closing testdata/example3.txt

func New

func New[V any](value V, ok bool) M[V]

New returns a M. It is syntax sugar for M{value, ok}. If ok is a known constant, use Some or Nothing instead.

func Nothing

func Nothing[V any]() M[V]

Nothing returns a (typed) M that has no value.

func Some

func Some[V any](value V) M[V]

Some returns a M that contains a value.

func (M[V]) Must added in v2.2.0

func (m M[V]) Must() V

Must returns a M's value. If the M is not ok, panics.

func (M[V]) MustNot added in v2.2.0

func (m M[V]) MustNot()

MustNot panics if the M is ok.

func (M[V]) Or added in v2.7.0

func (m M[V]) Or(v V) V

Or returns M.value if ok, otherwise returns the provided argument instead.

func (M[V]) Unpack added in v2.2.0

func (m M[V]) Unpack() (V, bool)

Unpack returns a plain (value, ok) tuple from a M.

Jump to

Keyboard shortcuts

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