maybe

package module
v0.0.0-...-8e0cb72 Latest Latest
Warning

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

Go to latest
Published: Oct 4, 2018 License: Apache-2.0 Imports: 3 Imported by: 0

README

GoDoc Build Status

maybe – A Maybe monad experiment for Go

Description

This package implements the Maybe monad for a couple basic types and arrays of those types. This allows "boxing" a value or error and chaining operations on the boxed type without constant error checking. See "Error Handling in Go: Rob Pike Reinvented Monads" for more on the concept.

This is an experiment to simplify some libraries the author is writing. It should not be considered stable for production use.

To keep type names short and manageable, abbreviations are used. Type maybe.I is for ints; maybe.AoI is short for "array of ints" and maybe.AoAoI is short for "array of array of ints".

This package only implements up to 2-D containers because those are common when working with line-oriented data. For example, a text file can be interpreted as an array of an array of characters.

Three constructors are provided for each type. The Just_ and Err_ constructors are for values and errors, respectively. The New_ constructor can construct either type, and is intended for wrapping functions that follow the pattern of returning a value and an error.

Example

package maybe_test

import (
	"fmt"
	"strconv"

	"github.com/xdg/maybe"
)

type example struct {
	label string
	data  []string
}

// Example shows how to convert a list of strings to a list of non-negative
// integers, accounting for the possibility of failure either in conversion
// or validation.
func Example() {

	cases := []example{
		{label: "success", data: []string{"23", "42", "0"}},
		{label: "bad atoi", data: []string{"23", "forty-two", "0"}},
		{label: "negative", data: []string{"23", "-42", "0"}},
	}

	// Function to convert string to maybe.I.
	atoi := func(s string) maybe.I { return maybe.NewI(strconv.Atoi(s)) }

	// Function to validate non-negative integer.
	validate := func(x int) maybe.I {
		if x < 0 {
			return maybe.ErrI(fmt.Errorf("%d is negative", x))
		}
		return maybe.JustI(x)
	}

	// For each example, try converting and validating functionally and
	// then inspecting the result.
	for _, c := range cases {
		// Wrap the []string in a maybe type.
		strs := maybe.JustAoS(c.data)

		// Functionally convert and validate.
		nums := strs.ToInt(atoi).Map(validate)

		// Check if it worked.
		if nums.IsErr() {
			fmt.Printf("%s: %v failed to convert: %v\n", c.label, strs, nums)
		} else {
			fmt.Printf("%s: %v converted to %v\n", c.label, strs, nums)
		}
	}

	// Output:
	// success: Just [23 42 0] converted to Just [23 42 0]
	// bad atoi: Just [23 forty-two 0] failed to convert: Err strconv.Atoi: parsing "forty-two": invalid syntax
	// negative: Just [23 -42 0] failed to convert: Err -42 is negative
}

Copyright 2017 by David A. Golden. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"). You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0

Documentation

Overview

Package maybe implements the Maybe monad for some basic types plus arrays and 2-D arrays of those types.

To keep type names short and manageable, abbreviations are used. Type `maybe.I` is for ints; `maybe.AoI` is short for "array of ints" and `maybe.AoAoI` is short for "array of array of ints".

This package only implements up to 2-D containers because those are common when working with line-oriented data. For example, a text file can be interpreted as an array of an array of characters.

Three constructors are provided for each type. The `Just_` and `Err_` constructors are for values and errors, respectively. The `New_` constructor can construct either type, and is intended for wrapping functions that follow the pattern of returning a value and an error.

Example

Example shows how to convert a list of strings to a list of non-negative integers, accounting for the possibility of failure either in conversion or validation.

//go:build go1.8
// +build go1.8

package main

import (
	"fmt"
	"strconv"

	"github.com/xdg/maybe"
)

type example struct {
	label string
	data  []string
}

// Example shows how to convert a list of strings to a list of non-negative
// integers, accounting for the possibility of failure either in conversion
// or validation.
func main() {

	cases := []example{
		{label: "success", data: []string{"23", "42", "0"}},
		{label: "bad atoi", data: []string{"23", "forty-two", "0"}},
		{label: "negative", data: []string{"23", "-42", "0"}},
	}

	// Function to convert string to maybe.I.
	atoi := func(s string) maybe.I { return maybe.NewI(strconv.Atoi(s)) }

	// Function to validate non-negative integer.
	validate := func(x int) maybe.I {
		if x < 0 {
			return maybe.ErrI(fmt.Errorf("%d is negative", x))
		}
		return maybe.JustI(x)
	}

	// For each example, try converting and validating functionally and
	// then inspecting the result.
	for _, c := range cases {
		// Wrap the []string in a maybe type.
		strs := maybe.JustAoS(c.data)

		// Functionally convert and validate.
		nums := strs.ToInt(atoi).Map(validate)

		// Check if it worked.
		if nums.IsErr() {
			fmt.Printf("%s: %v failed to convert: %v\n", c.label, strs, nums)
		} else {
			fmt.Printf("%s: %v converted to %v\n", c.label, strs, nums)
		}
	}

}
Output:

success: Just [23 42 0] converted to Just [23 42 0]
bad atoi: Just [23 forty-two 0] failed to convert: Err strconv.Atoi: parsing "forty-two": invalid syntax
negative: Just [23 -42 0] failed to convert: Err -42 is negative

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AoAoI

type AoAoI struct {
	// contains filtered or unexported fields
}

AoAoI implements the Maybe monad for a 2-D slice of ints. An AoAoI is considered 'valid' or 'invalid' depending on whether it contains a 2-D slice of ints or an error value. A zero-value AoAoI is invalid and Unbox() will return an error to that effect.

func ErrAoAoI

func ErrAoAoI(e error) AoAoI

ErrAoAoI constructs an invalid AoAoI from a given error.

func JustAoAoI

func JustAoAoI(s [][]int) AoAoI

JustAoAoI constructs a valid AoAoI from a given 2-D slice of ints.

func NewAoAoI

func NewAoAoI(s [][]int, e error) AoAoI

NewAoAoI constructs an AoAoI from a given 2-D slice of ints or error. If e is not nil, returns ErrAoAoI(e), otherwise returns JustAoAoI(s).

func (AoAoI) Bind

func (m AoAoI) Bind(f func(s [][]int) AoAoI) AoAoI

Bind applies a function that takes a 2-D slice of ints and returns an AoAoI.

func (AoAoI) Flatten

func (m AoAoI) Flatten() AoI

Flatten joins a 2-D slice of ints into a 1-D slice

func (AoAoI) IsErr

func (m AoAoI) IsErr() bool

IsErr returns true for an invalid AoAoI.

func (AoAoI) Join

func (m AoAoI) Join(f func(s []int) I) AoI

Join applies a function that takes a 2-D slice of ints and returns an AoI.

func (AoAoI) Map

func (m AoAoI) Map(f func(s []int) AoI) AoAoI

Map applies a function to each element of a valid AoAoI (i.e. a 1-D slice) and returns a new AoAoI. If the AoAoI is invalid or if any function returns an invalid AoI, Map returns an invalid AoAoI.

func (AoAoI) String

func (m AoAoI) String() string

String returns a string representation, mostly useful for debugging.

func (AoAoI) ToStr

func (m AoAoI) ToStr(f func(x int) S) AoAoS

ToStr applies a function that takes an int and returns an S. If the AoAoI is invalid or if any function returns an invalid S, ToStr returns an invalid AoAoS. Note: unlike Map, this is a deep conversion of individual elements of the 2-D slice of ints.

func (AoAoI) Unbox

func (m AoAoI) Unbox() ([][]int, error)

Unbox returns the underlying 2-D slice of ints or error.

type AoAoS

type AoAoS struct {
	// contains filtered or unexported fields
}

AoAoS implements the Maybe monad for a 2-D slice of strings. An AoAoS is considered 'valid' or 'invalid' depending on whether it contains a 2-D slice of strings or an error value. A zero-value AoAoS is invalid and Unbox() will return an error to that effect.

func ErrAoAoS

func ErrAoAoS(e error) AoAoS

ErrAoAoS constructs an invalid AoAoS from a given error.

func JustAoAoS

func JustAoAoS(s [][]string) AoAoS

JustAoAoS constructs a valid AoAoS from a given 2-D slice of strings.

func NewAoAoS

func NewAoAoS(s [][]string, e error) AoAoS

NewAoAoS constructs an AoAoS from a given 2-D slice of strings or error. If e is not nil, returns ErrAoAoS(e), otherwise returns JustAoAoS(s)

func (AoAoS) Bind

func (m AoAoS) Bind(f func(s [][]string) AoAoS) AoAoS

Bind applies a function that takes a 2-D slice of strings and returns an AoAoS.

func (AoAoS) Flatten

func (m AoAoS) Flatten() AoS

Flatten joins a 2-D slice of strings into a 1-D slice

func (AoAoS) IsErr

func (m AoAoS) IsErr() bool

IsErr returns true for an invalid AoAoS.

func (AoAoS) Join

func (m AoAoS) Join(f func(s []string) S) AoS

Join applies a function that takes a 2-D slice of strings and returns an AoS.

func (AoAoS) Map

func (m AoAoS) Map(f func(xs []string) AoS) AoAoS

Map applies a function to each element of a valid AoAoS (i.e. a 1-D slice) and returns a new AoAoS. If the AoAoS is invalid or if any function returns an invalid AoS, Map returns an invalid AoAoS.

func (AoAoS) String

func (m AoAoS) String() string

String returns a string representation, mostly useful for debugging.

func (AoAoS) ToInt

func (m AoAoS) ToInt(f func(s string) I) AoAoI

ToInt applies a function that takes a string and returns an I. If the AoAoS is invalid or if any function returns an invalid I, ToInt returns an invalid AoAoI. Note: unlike Map, this is a deep conversion of individual elements of the 2-D slice of strings.

func (AoAoS) Unbox

func (m AoAoS) Unbox() ([][]string, error)

Unbox returns the underlying 2-D slice of strings value or error.

type AoAoX

type AoAoX struct {
	// contains filtered or unexported fields
}

AoAoX implements the Maybe monad for a 2-D slice of empty interfaces. An AoAoX is considered 'valid' or 'invalid' depending on whether it contains a 2-D slice of empty interfaces or an error value. A zero-value AoAoX is invalid and Unbox() will return an error to that effect.

func ErrAoAoX

func ErrAoAoX(e error) AoAoX

ErrAoAoX constructs an invalid AoAoX from a given error.

func JustAoAoX

func JustAoAoX(x [][]interface{}) AoAoX

JustAoAoX constructs a valid AoAoX from a given 2-D slice of empty interfaces.

func NewAoAoX

func NewAoAoX(x [][]interface{}, e error) AoAoX

NewAoAoX constructs an AoAoX from a given 2-D slice of empty interfaces or error. If e is not nil, returns ErrAoAoX(e), otherwise returns JustAoAoX(x).

func NewAoAoXFromSlice

func NewAoAoXFromSlice(x interface{}, e error) AoAoX

NewAoAoXFromSlice constructs an AoAoX from a given slice of slices of arbitrary values or error. If e is not nil, returns ErrAoAoX(e), otherwise, the inner slices of values are converted to slices of empty interface and returned as JustAoAoX(x). If the provided value is not a slice of slices, ErrAoAoX is returned.

func (AoAoX) Bind

func (m AoAoX) Bind(f func(x [][]interface{}) AoAoX) AoAoX

Bind applies a function that takes a 2-D slice of empty interfaces and returns an AoAoX.

func (AoAoX) Flatten

func (m AoAoX) Flatten() AoX

Flatten joins a 2-D slice of empty interfaces into a 1-D slice

func (AoAoX) IsErr

func (m AoAoX) IsErr() bool

IsErr returns true for an invalid AoAoX.

func (AoAoX) Join

func (m AoAoX) Join(f func(x []interface{}) X) AoX

Join applies a function that takes a 2-D slice of empty interfaces and returns an AoX.

func (AoAoX) Map

func (m AoAoX) Map(f func(x []interface{}) AoX) AoAoX

Map applies a function to each element of a valid AoAoX (i.e. a 1-D slice) and returns a new AoAoX. If the AoAoX is invalid or if any function returns an invalid AoX, Map returns an invalid AoAoX.

func (AoAoX) String

func (m AoAoX) String() string

String returns a string representation, mostly useful for debugging.

func (AoAoX) Unbox

func (m AoAoX) Unbox() ([][]interface{}, error)

Unbox returns the underlying 2-D slice of empty interfaces or error.

type AoI

type AoI struct {
	// contains filtered or unexported fields
}

AoI implements the Maybe monad for a slice of ints. An AoI is considered 'valid' or 'invalid' depending on whether it contains a slice of ints or an error value. A zero-value AoI is invalid and Unbox() will return an error to that effect.

func ErrAoI

func ErrAoI(e error) AoI

ErrAoI constructs an invalid AoI from a given error.

func JustAoI

func JustAoI(s []int) AoI

JustAoI constructs a valid AoI from a given slice of ints.

func NewAoI

func NewAoI(s []int, e error) AoI

NewAoI constructs an AoI from a given slice of ints or error. If e is not nil, returns ErrAoI(e), otherwise returns JustAoI(s).

func (AoI) Bind

func (m AoI) Bind(f func(s []int) AoI) AoI

Bind applies a function that takes a slice of ints and returns an AoI.

func (AoI) IsErr

func (m AoI) IsErr() bool

IsErr returns true for an invalid AoI.

func (AoI) Join

func (m AoI) Join(f func(s []int) I) I

Join applies a function that takes a slice of ints and returns an I.

func (AoI) Map

func (m AoI) Map(f func(s int) I) AoI

Map applies a function to each element of a valid AoI and returns a new AoI. If the AoI is invalid or if any function returns an invalid I, Map returns an invalid AoI.

func (AoI) Split

func (m AoI) Split(f func(s int) AoI) AoAoI

Split applies a splitting function to each element of a valid AoI, resulting in a higher-dimension structure. If the AoI is invalid or if any function returns an invalid AoI, Split returns an invalid AoAoI.

func (AoI) String

func (m AoI) String() string

String returns a string representation, mostly useful for debugging.

func (AoI) ToStr

func (m AoI) ToStr(f func(x int) S) AoS

ToStr applies a function that takes an int and returns an S. If the AoI is invalid or if any function returns an invalid S, ToStr returns an invalid AoS.

func (AoI) Unbox

func (m AoI) Unbox() ([]int, error)

Unbox returns the underlying slice of ints or error.

type AoS

type AoS struct {
	// contains filtered or unexported fields
}

AoS implements the Maybe monad for a slice of strings. An AoS is considered 'valid' or 'invalid' depending on whether it contains a slice of strings or an error value. A zero-value AoS is invalid and Unbox() will return an error to that effect.

func ErrAoS

func ErrAoS(e error) AoS

ErrAoS constructs an invalid AoS from a given error.

func JustAoS

func JustAoS(s []string) AoS

JustAoS constructs a valid AoS from a given slice of strings.

func NewAoS

func NewAoS(s []string, e error) AoS

NewAoS constructs an AoS from a given slice of strings or error. If e is not nil, returns ErrAoS(e), otherwise returns JustAoS(s)

func (AoS) Bind

func (m AoS) Bind(f func(s []string) AoS) AoS

Bind applies a function that takes a slice of strings and returns an AoS.

func (AoS) IsErr

func (m AoS) IsErr() bool

IsErr returns true for an invalid AoS.

func (AoS) Join

func (m AoS) Join(f func(s []string) S) S

Join applies a function that takes a slice of strings and returns an S.

func (AoS) Map

func (m AoS) Map(f func(s string) S) AoS

Map applies a function to each element of a valid AoS and returns a new AoS. If the AoS is invalid or if any function returns an invalid S, Map returns an invalid AoS.

func (AoS) Split

func (m AoS) Split(f func(s string) AoS) AoAoS

Split applies a splitting function to each element of a valid AoS, resulting in a higher-dimension structure. If the AoS is invalid or if any function returns an invalid AoS, Split returns an invalid AoAoS.

func (AoS) String

func (m AoS) String() string

String returns a string representation, mostly useful for debugging.

func (AoS) ToInt

func (m AoS) ToInt(f func(s string) I) AoI

ToInt applies a function that takes a string and returns an I.If the AoS is invalid or if any function returns an invalid I, ToInt returns an invalid AoI.

func (AoS) Unbox

func (m AoS) Unbox() ([]string, error)

Unbox returns the underlying slice of strings value or error.

type AoX

type AoX struct {
	// contains filtered or unexported fields
}

AoX implements the Maybe monad for a slice of empty interfaces. An AoX is considered 'valid' or 'invalid' depending on whether it contains a slice of empty interfaces or an error value. A zero-value AoX is invalid and Unbox() will return an error to that effect.

func ErrAoX

func ErrAoX(e error) AoX

ErrAoX constructs an invalid AoX from a given error.

func JustAoX

func JustAoX(x []interface{}) AoX

JustAoX constructs a valid AoX from a given slice of empty interfaces.

func NewAoX

func NewAoX(x []interface{}, e error) AoX

NewAoX constructs an AoX from a given slice of empty interfaces or error. If e is not nil, returns ErrAoX(e), otherwise returns JustAoX(x).

func NewAoXFromSlice

func NewAoXFromSlice(x interface{}, e error) AoX

NewAoXFromSlice constructs an AoX from a given slice of arbitrary values or error. If e is not nil, returns ErrAoX(e), otherwise, the slice of values is converted to a slice of empty interface and returned as JustAoX(x). If the provided value is not a slice, ErrAoX is returned.

func (AoX) Bind

func (m AoX) Bind(f func(x []interface{}) AoX) AoX

Bind applies a function that takes a slice of empty interfaces and returns an AoX.

func (AoX) IsErr

func (m AoX) IsErr() bool

IsErr returns true for an invalid AoX.

func (AoX) Join

func (m AoX) Join(f func(x []interface{}) X) X

Join applies a function that takes a slice of empty interfaces and returns an I.

func (AoX) Map

func (m AoX) Map(f func(x interface{}) X) AoX

Map applies a function to each element of a valid AoX and returns a new AoX. If the AoX is invalid or if any function returns an invalid I, Map returns an invalid AoX.

func (AoX) Split

func (m AoX) Split(f func(x interface{}) AoX) AoAoX

Split applies a splitting function to each element of a valid AoX, resulting in a higher-dimension structure. If the AoX is invalid or if any function returns an invalid AoX, Split returns an invalid AoAoX.

func (AoX) String

func (m AoX) String() string

String returns a string representation, mostly useful for debugging.

func (AoX) Unbox

func (m AoX) Unbox() ([]interface{}, error)

Unbox returns the underlying slice of empty interfaces or error.

type I

type I struct {
	// contains filtered or unexported fields
}

I implements the Maybe monad for a int. An I is considered 'valid' or 'invalid' depending on whether it contains a int or an error value.

func ErrI

func ErrI(e error) I

ErrI constructs an invalid I from a given error.

func JustI

func JustI(s int) I

JustI constructs a valid I from a given int.

func NewI

func NewI(s int, e error) I

NewI constructs an I from a given int or error. If e is not nil, returns ErrI(e), otherwise returns JustI(s)

func (I) Bind

func (m I) Bind(f func(s int) I) I

Bind applies a function that takes a int and returns an I.

func (I) IsErr

func (m I) IsErr() bool

IsErr returns true for an invalid I.

func (I) Split

func (m I) Split(f func(s int) AoI) AoI

Split applies a function that takes a int and returns an AoI.

func (I) String

func (m I) String() string

String returns a string representation, mostly useful for debugging.

func (I) ToStr

func (m I) ToStr(f func(x int) S) S

ToStr applies a function that takes an int and returns an S.

func (I) Unbox

func (m I) Unbox() (int, error)

Unbox returns the underlying int value or error.

type S

type S struct {
	// contains filtered or unexported fields
}

S implements the Maybe monad for a string. An S is considered 'valid' or 'invalid' depending on whether it contains a string or an error value.

func ErrS

func ErrS(e error) S

ErrS constructs an invalid S from a given error.

func JustS

func JustS(s string) S

JustS constructs a valid S from a given string.

func NewS

func NewS(s string, e error) S

NewS constructs an S from a given string or error. If e is not nil, returns ErrS(e), otherwise returns JustS(s)

func (S) Bind

func (m S) Bind(f func(s string) S) S

Bind applies a function that takes a string and returns an S.

func (S) IsErr

func (m S) IsErr() bool

IsErr returns true for an invalid S.

func (S) Split

func (m S) Split(f func(s string) AoS) AoS

Split applies a function that takes a string and returns an AoS.

func (S) String

func (m S) String() string

String returns a string representation, mostly useful for debugging.

func (S) ToInt

func (m S) ToInt(f func(s string) I) I

ToInt applies a function that takes a string and returns an I.

func (S) Unbox

func (m S) Unbox() (string, error)

Unbox returns the underlying string value or error.

type X

type X struct {
	// contains filtered or unexported fields
}

X implements the Maybe monad for an empty interface. An X is considered 'valid' or 'invalid' depending on whether it contains a non-nil interface or an error value.

func ErrX

func ErrX(e error) X

ErrX constructs an invalid X from a given error.

func JustX

func JustX(x interface{}) X

JustX constructs a valid X from a given empty interface.

func NewX

func NewX(x interface{}, e error) X

NewX constructs an X from a given empty interface or error. If e is not nil, returns ErrX(e), otherwise returns JustX(s)

func (X) Bind

func (m X) Bind(f func(x interface{}) X) X

Bind applies a function that takes an interface and returns an X.

func (X) IsErr

func (m X) IsErr() bool

IsErr returns true for an invalid X.

func (X) Split

func (m X) Split(f func(x interface{}) AoX) AoX

Split applies a function that takes an interface and returns an AoX.

func (X) String

func (m X) String() string

String returns a string representation, mostly useful for debugging.

func (X) Unbox

func (m X) Unbox() (interface{}, error)

Unbox returns the underlying empty interface value or error.

Jump to

Keyboard shortcuts

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