option

package
v2.0.1 Latest Latest
Warning

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

Go to latest
Published: Dec 18, 2025 License: Apache-2.0 Imports: 28 Imported by: 0

Documentation

Overview

Package option defines the Option data structure and its monadic operations.

Option represents an optional value: every Option is either Some and contains a value, or None, and does not contain a value. This is a type-safe alternative to using nil pointers or special sentinel values to represent the absence of a value.

Fantasy Land Specification

This implementation corresponds to the Fantasy Land Maybe type: https://github.com/fantasyland/fantasy-land#maybe

Implemented Fantasy Land algebras:

Basic Usage

Create an Option with Some or None:

opt := Some(42)           // Option containing 42
opt := None[int]()        // Empty Option
opt := Of(42)             // Alternative to Some

Check if an Option contains a value:

if IsSome(opt) {
    // opt contains a value
}
if IsNone(opt) {
    // opt is empty
}

Extract values:

value, ok := Unwrap(opt)  // Returns (value, true) or (zero, false)
value := GetOrElse(func() int { return 0 })(opt)  // Returns value or default

Transformations

Map transforms the contained value:

result := Map(func(x int) string {
    return fmt.Sprintf("%d", x)
})(Some(42))  // Some("42")

Chain sequences operations that may fail:

result := Chain(func(x int) Option[int] {
    if x > 0 { return Some(x * 2) }
    return None[int]()
})(Some(5))  // Some(10)

Filter keeps values that satisfy a predicate:

result := Filter(func(x int) bool {
    return x > 0
})(Some(5))  // Some(5)

Working with Collections

Transform arrays:

result := TraverseArray(func(x int) Option[int] {
    if x > 0 { return Some(x * 2) }
    return None[int]()
})([]int{1, 2, 3})  // Some([2, 4, 6])

Sequence arrays of Options:

result := SequenceArray([]Option[int]{
    Some(1), Some(2), Some(3),
})  // Some([1, 2, 3])

Compact arrays (remove None values):

result := CompactArray([]Option[int]{
    Some(1), None[int](), Some(3),
})  // [1, 3]

Algebraic Operations

Option supports various algebraic structures:

  • Functor: Map operations
  • Applicative: Ap operations for applying wrapped functions
  • Monad: Chain operations for sequencing computations
  • Eq: Equality comparison
  • Ord: Ordering comparison
  • Semigroup/Monoid: Combining Options

Error Handling

Convert error-returning functions:

result := TryCatch(func() (int, error) {
    return strconv.Atoi("42")
})  // Some(42)

Convert validation functions:

parse := FromValidation(func(s string) (int, bool) {
    n, err := strconv.Atoi(s)
    return n, err == nil
})
result := parse("42")  // Some(42)

Subpackages

  • option/number: Number conversion utilities (Atoi, Itoa)
  • option/testing: Testing utilities for verifying monad laws

package option implements the Option monad, a data type that can have a defined value or none

Example (None_formatting)

Example_none_formatting demonstrates formatting of None values.

package main

import (
	"fmt"

	O "github.com/IBM/fp-go/v2/option"
)

func main() {
	none := O.None[string]()

	fmt.Printf("String():   %s\n", none.String())
	fmt.Printf("GoString(): %s\n", none.GoString())
	fmt.Printf("%%v:         %v\n", none)
	fmt.Printf("%%#v:        %#v\n", none)

}
Output:

String():   None[string]
GoString(): option.None[string]
%v:         None[string]
%#v:        option.None[string]

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func AltMonoid

func AltMonoid[A any]() M.Monoid[Option[A]]

AltMonoid creates a Monoid for Option[A] using the Alt operation. This monoid returns the first Some value, or None if both are None. The empty value is None.

Example:

optMonoid := AltMonoid[int]()
optMonoid.Concat(Some(2), Some(3)) // Some(2) - returns first Some
optMonoid.Concat(None[int](), Some(3)) // Some(3)
optMonoid.Empty() // None

func AlternativeMonoid

func AlternativeMonoid[A any](m M.Monoid[A]) M.Monoid[Option[A]]

AlternativeMonoid creates a Monoid for Option[A] using the alternative semantics. This combines the applicative functor structure with the alternative (Alt) operation.

Example:

intMonoid := monoid.MakeMonoid(func(a, b int) int { return a + b }, 0)
optMonoid := AlternativeMonoid(intMonoid)
result := optMonoid.Concat(Some(2), Some(3)) // Some(5)

func ApplicativeMonoid

func ApplicativeMonoid[A any](m M.Monoid[A]) M.Monoid[Option[A]]

ApplicativeMonoid returns a Monoid that concatenates Option instances via their applicative functor. This combines the monoid structure of the underlying type with the Option structure.

Example:

intMonoid := monoid.MakeMonoid(func(a, b int) int { return a + b }, 0)
optMonoid := ApplicativeMonoid(intMonoid)
result := optMonoid.Concat(Some(2), Some(3)) // Some(5)
result := optMonoid.Empty() // Some(0)

func ApplySemigroup

func ApplySemigroup[A any](s S.Semigroup[A]) S.Semigroup[Option[A]]

ApplySemigroup lifts a Semigroup over a type A to a Semigroup over Option[A]. The resulting semigroup combines two Options using the applicative functor pattern.

Example:

intSemigroup := semigroup.MakeSemigroup(func(a, b int) int { return a + b })
optSemigroup := ApplySemigroup(intSemigroup)
result := optSemigroup.Concat(Some(2), Some(3)) // Some(5)
result := optSemigroup.Concat(Some(2), None[int]()) // None

func CompactArray

func CompactArray[A any](fa []Option[A]) []A

CompactArray filters an array of Options, keeping only the Some values and discarding None values.

Example:

input := []Option[int]{Some(1), None[int](), Some(3), Some(5), None[int]()}
result := CompactArray(input) // [1, 3, 5]

func CompactArrayG

func CompactArrayG[A1 ~[]Option[A], A2 ~[]A, A any](fa A1) A2

CompactArrayG filters an array of Options, keeping only the Some values and discarding None values. This is the generic version that works with custom slice types.

Example:

type MySlice []int
input := []Option[int]{Some(1), None[int](), Some(3)}
result := CompactArrayG[[]Option[int], MySlice](input) // MySlice{1, 3}

func CompactRecord

func CompactRecord[K comparable, A any](m map[K]Option[A]) map[K]A

CompactRecord filters a map of Options, keeping only the Some values and discarding None values.

Example:

input := map[string]Option[int]{"a": Some(1), "b": None[int](), "c": Some(3)}
result := CompactRecord(input) // map[a:1 c:3]

func CompactRecordG

func CompactRecordG[M1 ~map[K]Option[A], M2 ~map[K]A, K comparable, A any](m M1) M2

CompactRecordG filters a map of Options, keeping only the Some values and discarding None values. This is the generic version that works with custom map types.

Example:

type MyMap map[string]int
input := map[string]Option[int]{"a": Some(1), "b": None[int](), "c": Some(3)}
result := CompactRecordG[map[string]Option[int], MyMap](input) // MyMap{"a": 1, "c": 3}

func Eq

func Eq[A any](a EQ.Eq[A]) EQ.Eq[Option[A]]

Eq constructs an equality predicate for Option[A] given an equality predicate for A. Two Options are equal if:

  • Both are None, or
  • Both are Some and their contained values are equal according to the provided Eq

Example:

intEq := eq.FromStrictEquals[int]()
optEq := Eq(intEq)
optEq.Equals(Some(42), Some(42)) // true
optEq.Equals(Some(42), Some(43)) // false
optEq.Equals(None[int](), None[int]()) // true
optEq.Equals(Some(42), None[int]()) // false

func Fold

func Fold[A, B any](onNone func() B, onSome func(a A) B) func(ma Option[A]) B

Fold provides a way to handle both Some and None cases of an Option. Returns a function that applies onNone if the Option is None, or onSome if it's Some.

Example:

handler := Fold(
    func() string { return "no value" },
    func(x int) string { return fmt.Sprintf("value: %d", x) },
)
result := handler(Some(42)) // "value: 42"
result := handler(None[int]()) // "no value"

func FromEq

func FromEq[A any](pred eq.Eq[A]) func(A) Kleisli[A, A]

func FromStrictCompare

func FromStrictCompare[A C.Ordered]() ord.Ord[Option[A]]

FromStrictCompare constructs an Ord for Option[A] using Go's built-in comparison operators for type A. This is a convenience function for ordered types (types that support <, >, ==).

Example:

optOrd := FromStrictCompare[int]()
optOrd.Compare(Some(5), Some(10)) // -1
optOrd.Compare(None[int](), Some(5)) // -1

func FromStrictEq

func FromStrictEq[A comparable]() func(A) Kleisli[A, A]

func FromStrictEquals

func FromStrictEquals[A comparable]() EQ.Eq[Option[A]]

FromStrictEquals constructs an Eq for Option[A] using Go's built-in equality (==) for type A. This is a convenience function for comparable types.

Example:

optEq := FromStrictEquals[int]()
optEq.Equals(Some(42), Some(42)) // true
optEq.Equals(None[int](), None[int]()) // true

func Functor

func Functor[A, B any]() functor.Functor[A, B, Option[A], Option[B]]

Functor implements the functoric operations for Option. A functor is a type that can be mapped over, transforming the contained value while preserving the structure.

Example:

f := Functor[int, string]()
mapper := f.Map(strconv.Itoa)
result := mapper(Some(42)) // Some("42")

func GetOrElse

func GetOrElse[A any](onNone func() A) func(Option[A]) A

GetOrElse returns a function that extracts the value from an Option or returns a default.

Example:

getOrZero := GetOrElse(func() int { return 0 })
result := getOrZero(Some(42)) // 42
result := getOrZero(None[int]()) // 0

func IsNone

func IsNone[T any](val Option[T]) bool

IsNone checks if an Option is None (contains no value).

Example:

opt := None[int]()
IsNone(opt) // true
opt := Some(42)
IsNone(opt) // false

func IsSome

func IsSome[T any](val Option[T]) bool

IsSome checks if an Option contains a value.

Example:

opt := Some(42)
IsSome(opt) // true
opt := None[int]()
IsSome(opt) // false

func Logger

func Logger[A any](loggers ...*log.Logger) func(string) Kleisli[Option[A], A]

Logger creates a logging function for Options that logs the state (None or Some with value) and returns the original Option unchanged. This is useful for debugging pipelines.

Parameters:

  • loggers: optional log.Logger instances to use for logging (defaults to standard logger)

Returns a function that takes a prefix string and returns a function that logs and passes through an Option.

Example:

logger := Logger[int]()
result := F.Pipe2(
    Some(42),
    logger("step1"), // logs "step1: 42"
    Map(N.Mul(2)),
) // Some(84)

result := F.Pipe1(
    None[int](),
    logger("step1"), // logs "step1"
) // None

func Monad

func Monad[A, B any]() monad.Monad[A, B, Option[A], Option[B], Option[func(A) B]]

Monad implements the monadic operations for Option. A monad provides a way to chain computations that may fail, handling the None case automatically.

The monad interface includes:

  • Of: wraps a value in an Option
  • Map: transforms the contained value
  • Chain: sequences Option-returning operations
  • Ap: applies an Option-wrapped function to an Option-wrapped value

Example:

m := Monad[int, string]()
result := m.Chain(func(x int) Option[string] {
    if x > 0 { return Some(fmt.Sprintf("%d", x)) }
    return None[string]()
})(Some(42)) // Some("42")

func MonadFold

func MonadFold[A, B any](ma Option[A], onNone func() B, onSome func(A) B) B

MonadFold performs a fold operation on an Option. If the Option is Some, applies onSome to the value. If the Option is None, calls onNone.

Example:

opt := Some(42)
result := MonadFold(opt,
    func() string { return "no value" },
    func(x int) string { return fmt.Sprintf("value: %d", x) },
) // "value: 42"

func MonadGetOrElse

func MonadGetOrElse[A any](fa Option[A], onNone func() A) A

MonadGetOrElse extracts the value from an Option or returns a default value. This is the monadic form of GetOrElse.

Example:

result := MonadGetOrElse(Some(42), func() int { return 0 }) // 42
result := MonadGetOrElse(None[int](), func() int { return 0 }) // 0

func Monoid

func Monoid[A any]() func(S.Semigroup[A]) M.Monoid[Option[A]]

Monoid returns a function that lifts a Semigroup over type A to a Monoid over Option[A]. The monoid returns the left-most non-None value. If both operands are Some, their inner values are concatenated using the provided Semigroup. The empty value is None.

Truth table:

| x       | y       | concat(x, y)       |
| ------- | ------- | ------------------ |
| none    | none    | none               |
| some(a) | none    | some(a)            |
| none    | some(b) | some(b)            |
| some(a) | some(b) | some(concat(a, b)) |

Example:

intSemigroup := semigroup.MakeSemigroup(func(a, b int) int { return a + b })
optMonoid := Monoid[int]()(intSemigroup)
optMonoid.Concat(Some(2), Some(3)) // Some(5)
optMonoid.Empty() // None

func Optionize0

func Optionize0[F ~func() (R, bool), R any](f F) func() Option[R]

Optionize0 converts a function with 0 parameters returning a tuple of a return value R and a boolean into a function with 0 parameters returning an Option[R]

func Optionize10

func Optionize10[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (R, bool), T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) Option[R]

Optionize10 converts a function with 10 parameters returning a tuple of a return value R and a boolean into a function with 10 parameters returning an Option[R]

func Optionize2

func Optionize2[F ~func(T0, T1) (R, bool), T0, T1, R any](f F) func(T0, T1) Option[R]

Optionize2 converts a function with 2 parameters returning a tuple of a return value R and a boolean into a function with 2 parameters returning an Option[R]

func Optionize3

func Optionize3[F ~func(T0, T1, T2) (R, bool), T0, T1, T2, R any](f F) func(T0, T1, T2) Option[R]

Optionize3 converts a function with 3 parameters returning a tuple of a return value R and a boolean into a function with 3 parameters returning an Option[R]

func Optionize4

func Optionize4[F ~func(T0, T1, T2, T3) (R, bool), T0, T1, T2, T3, R any](f F) func(T0, T1, T2, T3) Option[R]

Optionize4 converts a function with 4 parameters returning a tuple of a return value R and a boolean into a function with 4 parameters returning an Option[R]

func Optionize5

func Optionize5[F ~func(T0, T1, T2, T3, T4) (R, bool), T0, T1, T2, T3, T4, R any](f F) func(T0, T1, T2, T3, T4) Option[R]

Optionize5 converts a function with 5 parameters returning a tuple of a return value R and a boolean into a function with 5 parameters returning an Option[R]

func Optionize6

func Optionize6[F ~func(T0, T1, T2, T3, T4, T5) (R, bool), T0, T1, T2, T3, T4, T5, R any](f F) func(T0, T1, T2, T3, T4, T5) Option[R]

Optionize6 converts a function with 6 parameters returning a tuple of a return value R and a boolean into a function with 6 parameters returning an Option[R]

func Optionize7

func Optionize7[F ~func(T0, T1, T2, T3, T4, T5, T6) (R, bool), T0, T1, T2, T3, T4, T5, T6, R any](f F) func(T0, T1, T2, T3, T4, T5, T6) Option[R]

Optionize7 converts a function with 7 parameters returning a tuple of a return value R and a boolean into a function with 7 parameters returning an Option[R]

func Optionize8

func Optionize8[F ~func(T0, T1, T2, T3, T4, T5, T6, T7) (R, bool), T0, T1, T2, T3, T4, T5, T6, T7, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7) Option[R]

Optionize8 converts a function with 8 parameters returning a tuple of a return value R and a boolean into a function with 8 parameters returning an Option[R]

func Optionize9

func Optionize9[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8) (R, bool), T0, T1, T2, T3, T4, T5, T6, T7, T8, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8) Option[R]

Optionize9 converts a function with 9 parameters returning a tuple of a return value R and a boolean into a function with 9 parameters returning an Option[R]

func Ord

func Ord[A any](a ord.Ord[A]) ord.Ord[Option[A]]

Ord constructs an ordering for Option[A] given an ordering for A. The ordering follows these rules:

  • None is considered less than any Some value
  • Two None values are equal
  • Two Some values are compared using the provided Ord for A

Example:

intOrd := ord.FromStrictCompare[int]()
optOrd := Ord(intOrd)
optOrd.Compare(None[int](), Some(5)) // -1 (None < Some)
optOrd.Compare(Some(3), Some(5)) // -1 (3 < 5)
optOrd.Compare(Some(5), Some(3)) // 1 (5 > 3)
optOrd.Compare(None[int](), None[int]()) // 0 (equal)

func Pointed

func Pointed[A any]() pointed.Pointed[A, Option[A]]

Pointed implements the Pointed operations for Option. A pointed functor is a functor with an Of operation that wraps a value.

Example:

p := Pointed[int]()
result := p.Of(42) // Some(42)

func Reduce

func Reduce[A, B any](f func(B, A) B, initial B) func(Option[A]) B

Reduce folds an Option into a single value using a reducer function. If the Option is None, returns the initial value.

Example:

sum := Reduce(func(acc, val int) int { return acc + val }, 0)
result := sum(Some(5)) // 5
result := sum(None[int]()) // 0

func Semigroup

func Semigroup[A any]() func(S.Semigroup[A]) S.Semigroup[Option[A]]

Semigroup returns a function that lifts a Semigroup over type A to a Semigroup over Option[A]. The resulting semigroup combines two Options according to these rules:

  • If both are Some, concatenates their values using the provided Semigroup
  • If one is None, returns the other
  • If both are None, returns None

Example:

intSemigroup := semigroup.MakeSemigroup(func(a, b int) int { return a + b })
optSemigroup := Semigroup[int]()(intSemigroup)
optSemigroup.Concat(Some(2), Some(3)) // Some(5)
optSemigroup.Concat(Some(2), None[int]()) // Some(2)
optSemigroup.Concat(None[int](), Some(3)) // Some(3)

func Sequence

func Sequence[A, HKTA, HKTOA any](
	mof func(Option[A]) HKTOA,
	mmap func(Kleisli[A, A]) func(HKTA) HKTOA,
) func(Option[HKTA]) HKTOA

Sequence converts an Option of some higher kinded type into the higher kinded type of an Option. This is a generic sequencing operation that works with any applicative functor.

Parameters:

  • mof: wraps an Option in the target higher kinded type
  • mmap: maps a function over the higher kinded type

Example (conceptual - typically used with other monadic types):

// Sequencing Option[IO[A]] to IO[Option[A]]
result := Sequence[int, IO[int], IO[Option[int]]](
    func(opt Option[int]) IO[Option[int]] { return IO.Of(opt) },
    func(f func(int) Option[int]) func(IO[int]) IO[Option[int]] { ... },
)

func Sequence2

func Sequence2[T1, T2, R any](f func(T1, T2) Option[R]) func(Option[T1], Option[T2]) Option[R]

Sequence2 returns a function that sequences two Options with a combining function.

Example:

add := Sequence2(func(a, b int) Option[int] { return Some(a + b) })
result := add(Some(2), Some(3)) // Some(5)

func Traverse

func Traverse[A, B, HKTB, HKTOB any](
	mof func(Option[B]) HKTOB,
	mmap func(Kleisli[B, B]) func(HKTB) HKTOB,
) func(func(A) HKTB) func(Option[A]) HKTOB

Traverse converts an Option by applying a function that produces a higher kinded type, then sequences the result. This combines mapping and sequencing in one operation.

Parameters:

  • mof: wraps an Option in the target higher kinded type
  • mmap: maps a function over the higher kinded type

Returns a function that takes a transformation function and an Option, producing the higher kinded type containing an Option.

Example (conceptual - typically used with other monadic types):

// Traversing Option[A] with a function A -> IO[B] to get IO[Option[B]]
result := Traverse[int, string, IO[string], IO[Option[string]]](
    func(opt Option[string]) IO[Option[string]] { return IO.Of(opt) },
    func(f func(string) Option[string]) func(IO[string]) IO[Option[string]] { ... },
)

func TraverseTuple1

func TraverseTuple1[F1 ~Kleisli[A1, T1], A1, T1 any](f1 F1) func(T.Tuple1[A1]) Option[T.Tuple1[T1]]

TraverseTuple1 converts a [Tuple1] of [A] via transformation functions transforming [A] to [Option[A]] into a [Option[Tuple1]].

func TraverseTuple10

func TraverseTuple10[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], F6 ~Kleisli[A6, T6], F7 ~Kleisli[A7, T7], F8 ~Kleisli[A8, T8], F9 ~Kleisli[A9, T9], F10 ~Kleisli[A10, T10], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8, A9, T9, A10, T10 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) func(T.Tuple10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]) Option[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]

TraverseTuple10 converts a [Tuple10] of [A] via transformation functions transforming [A] to [Option[A]] into a [Option[Tuple10]].

func TraverseTuple2

func TraverseTuple2[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], A1, T1, A2, T2 any](f1 F1, f2 F2) func(T.Tuple2[A1, A2]) Option[T.Tuple2[T1, T2]]

TraverseTuple2 converts a [Tuple2] of [A] via transformation functions transforming [A] to [Option[A]] into a [Option[Tuple2]].

func TraverseTuple3

func TraverseTuple3[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], A1, T1, A2, T2, A3, T3 any](f1 F1, f2 F2, f3 F3) func(T.Tuple3[A1, A2, A3]) Option[T.Tuple3[T1, T2, T3]]

TraverseTuple3 converts a [Tuple3] of [A] via transformation functions transforming [A] to [Option[A]] into a [Option[Tuple3]].

func TraverseTuple4

func TraverseTuple4[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], A1, T1, A2, T2, A3, T3, A4, T4 any](f1 F1, f2 F2, f3 F3, f4 F4) func(T.Tuple4[A1, A2, A3, A4]) Option[T.Tuple4[T1, T2, T3, T4]]

TraverseTuple4 converts a [Tuple4] of [A] via transformation functions transforming [A] to [Option[A]] into a [Option[Tuple4]].

func TraverseTuple5

func TraverseTuple5[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5) func(T.Tuple5[A1, A2, A3, A4, A5]) Option[T.Tuple5[T1, T2, T3, T4, T5]]

TraverseTuple5 converts a [Tuple5] of [A] via transformation functions transforming [A] to [Option[A]] into a [Option[Tuple5]].

func TraverseTuple6

func TraverseTuple6[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], F6 ~Kleisli[A6, T6], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6) func(T.Tuple6[A1, A2, A3, A4, A5, A6]) Option[T.Tuple6[T1, T2, T3, T4, T5, T6]]

TraverseTuple6 converts a [Tuple6] of [A] via transformation functions transforming [A] to [Option[A]] into a [Option[Tuple6]].

func TraverseTuple7

func TraverseTuple7[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], F6 ~Kleisli[A6, T6], F7 ~Kleisli[A7, T7], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7) func(T.Tuple7[A1, A2, A3, A4, A5, A6, A7]) Option[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]]

TraverseTuple7 converts a [Tuple7] of [A] via transformation functions transforming [A] to [Option[A]] into a [Option[Tuple7]].

func TraverseTuple8

func TraverseTuple8[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], F6 ~Kleisli[A6, T6], F7 ~Kleisli[A7, T7], F8 ~Kleisli[A8, T8], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8) func(T.Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]) Option[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]

TraverseTuple8 converts a [Tuple8] of [A] via transformation functions transforming [A] to [Option[A]] into a [Option[Tuple8]].

func TraverseTuple9

func TraverseTuple9[F1 ~Kleisli[A1, T1], F2 ~Kleisli[A2, T2], F3 ~Kleisli[A3, T3], F4 ~Kleisli[A4, T4], F5 ~Kleisli[A5, T5], F6 ~Kleisli[A6, T6], F7 ~Kleisli[A7, T7], F8 ~Kleisli[A8, T8], F9 ~Kleisli[A9, T9], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8, A9, T9 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9) func(T.Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]) Option[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]

TraverseTuple9 converts a [Tuple9] of [A] via transformation functions transforming [A] to [Option[A]] into a [Option[Tuple9]].

func Unoptionize0

func Unoptionize0[F ~func() Option[R], R any](f F) func() (R, bool)

Unoptionize0 converts a function with 0 parameters returning a tuple of a return value R and a boolean into a function with 0 parameters returning an Option[R]

func Unoptionize1

func Unoptionize1[F ~Kleisli[T0, R], T0, R any](f F) func(T0) (R, bool)

Unoptionize1 converts a function with 1 parameters returning a tuple of a return value R and a boolean into a function with 1 parameters returning an Option[R]

func Unoptionize10

func Unoptionize10[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) Option[R], T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (R, bool)

Unoptionize10 converts a function with 10 parameters returning a tuple of a return value R and a boolean into a function with 10 parameters returning an Option[R]

func Unoptionize2

func Unoptionize2[F ~func(T0, T1) Option[R], T0, T1, R any](f F) func(T0, T1) (R, bool)

Unoptionize2 converts a function with 2 parameters returning a tuple of a return value R and a boolean into a function with 2 parameters returning an Option[R]

func Unoptionize3

func Unoptionize3[F ~func(T0, T1, T2) Option[R], T0, T1, T2, R any](f F) func(T0, T1, T2) (R, bool)

Unoptionize3 converts a function with 3 parameters returning a tuple of a return value R and a boolean into a function with 3 parameters returning an Option[R]

func Unoptionize4

func Unoptionize4[F ~func(T0, T1, T2, T3) Option[R], T0, T1, T2, T3, R any](f F) func(T0, T1, T2, T3) (R, bool)

Unoptionize4 converts a function with 4 parameters returning a tuple of a return value R and a boolean into a function with 4 parameters returning an Option[R]

func Unoptionize5

func Unoptionize5[F ~func(T0, T1, T2, T3, T4) Option[R], T0, T1, T2, T3, T4, R any](f F) func(T0, T1, T2, T3, T4) (R, bool)

Unoptionize5 converts a function with 5 parameters returning a tuple of a return value R and a boolean into a function with 5 parameters returning an Option[R]

func Unoptionize6

func Unoptionize6[F ~func(T0, T1, T2, T3, T4, T5) Option[R], T0, T1, T2, T3, T4, T5, R any](f F) func(T0, T1, T2, T3, T4, T5) (R, bool)

Unoptionize6 converts a function with 6 parameters returning a tuple of a return value R and a boolean into a function with 6 parameters returning an Option[R]

func Unoptionize7

func Unoptionize7[F ~func(T0, T1, T2, T3, T4, T5, T6) Option[R], T0, T1, T2, T3, T4, T5, T6, R any](f F) func(T0, T1, T2, T3, T4, T5, T6) (R, bool)

Unoptionize7 converts a function with 7 parameters returning a tuple of a return value R and a boolean into a function with 7 parameters returning an Option[R]

func Unoptionize8

func Unoptionize8[F ~func(T0, T1, T2, T3, T4, T5, T6, T7) Option[R], T0, T1, T2, T3, T4, T5, T6, T7, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7) (R, bool)

Unoptionize8 converts a function with 8 parameters returning a tuple of a return value R and a boolean into a function with 8 parameters returning an Option[R]

func Unoptionize9

func Unoptionize9[F ~func(T0, T1, T2, T3, T4, T5, T6, T7, T8) Option[R], T0, T1, T2, T3, T4, T5, T6, T7, T8, R any](f F) func(T0, T1, T2, T3, T4, T5, T6, T7, T8) (R, bool)

Unoptionize9 converts a function with 9 parameters returning a tuple of a return value R and a boolean into a function with 9 parameters returning an Option[R]

func Unwrap

func Unwrap[A any](ma Option[A]) (A, bool)

Unwrap extracts the value and presence flag from an Option. Returns the value and true if Some, or zero value and false if None.

Example:

opt := Some(42)
val, ok := Unwrap(opt) // val = 42, ok = true
opt := None[int]()
val, ok := Unwrap(opt) // val = 0, ok = false

Types

type Endomorphism

type Endomorphism[T any] = endomorphism.Endomorphism[T]

type Kleisli

type Kleisli[A, B any] = func(A) Option[B]

func FromNonZero

func FromNonZero[A comparable]() Kleisli[A, A]

func FromPredicate

func FromPredicate[A any](pred func(A) bool) Kleisli[A, A]

FromPredicate returns a function that creates an Option based on a predicate. The returned function will wrap a value in Some if the predicate is satisfied, otherwise None.

Example:

isPositive := FromPredicate(func(n int) bool { return n > 0 })
result := isPositive(5)  // Some(5)
result := isPositive(-1) // None

func FromValidation

func FromValidation[A, B any](f func(A) (B, bool)) Kleisli[A, B]

FromValidation converts a validation function (returning value and bool) to an Option-returning function. This is an alias for Optionize1.

Example:

parseNum := FromValidation(func(s string) (int, bool) {
    n, err := strconv.Atoi(s)
    return n, err == nil
})
result := parseNum("42") // Some(42)

func FromZero

func FromZero[A comparable]() Kleisli[A, A]

func Optionize1

func Optionize1[F ~func(T0) (R, bool), T0, R any](f F) Kleisli[T0, R]

Optionize1 converts a function with 1 parameters returning a tuple of a return value R and a boolean into a function with 1 parameters returning an Option[R]

func TraverseArray

func TraverseArray[A, B any](f Kleisli[A, B]) Kleisli[[]A, []B]

TraverseArray transforms an array by applying a function that returns an Option to each element. Returns Some containing the array of results if all operations succeed, None if any fails.

Example:

validate := func(x int) Option[int] {
    if x > 0 { return Some(x * 2) }
    return None[int]()
}
result := TraverseArray(validate)([]int{1, 2, 3}) // Some([2, 4, 6])
result := TraverseArray(validate)([]int{1, -1, 3}) // None

func TraverseArrayG

func TraverseArrayG[GA ~[]A, GB ~[]B, A, B any](f Kleisli[A, B]) Kleisli[GA, GB]

TraverseArrayG transforms an array by applying a function that returns an Option to each element. Returns Some containing the array of results if all operations succeed, None if any fails. This is the generic version that works with custom slice types.

Example:

parse := func(s string) Option[int] {
    n, err := strconv.Atoi(s)
    if err != nil { return None[int]() }
    return Some(n)
}
result := TraverseArrayG[[]string, []int](parse)([]string{"1", "2", "3"}) // Some([1, 2, 3])
result := TraverseArrayG[[]string, []int](parse)([]string{"1", "x", "3"}) // None

func TraverseArrayWithIndex

func TraverseArrayWithIndex[A, B any](f func(int, A) Option[B]) Kleisli[[]A, []B]

TraverseArrayWithIndex transforms an array by applying an indexed function that returns an Option. The function receives both the index and the element.

Example:

f := func(i int, x int) Option[int] {
    if x > i { return Some(x) }
    return None[int]()
}
result := TraverseArrayWithIndex(f)([]int{1, 2, 3}) // Some([1, 2, 3])

func TraverseArrayWithIndexG

func TraverseArrayWithIndexG[GA ~[]A, GB ~[]B, A, B any](f func(int, A) Option[B]) Kleisli[GA, GB]

TraverseArrayWithIndexG transforms an array by applying an indexed function that returns an Option. The function receives both the index and the element. This is the generic version that works with custom slice types.

Example:

f := func(i int, s string) Option[string] {
    return Some(fmt.Sprintf("%d:%s", i, s))
}
result := TraverseArrayWithIndexG[[]string, []string](f)([]string{"a", "b"}) // Some(["0:a", "1:b"])

func TraverseIter

func TraverseIter[A, B any](f Kleisli[A, B]) Kleisli[Seq[A], Seq[B]]

TraverseIter transforms a sequence by applying a function that returns an Option to each element. Returns Some containing a sequence of results if all operations succeed, None if any fails. This function is useful for processing sequences where each element may fail validation or transformation.

The traversal short-circuits on the first None encountered, making it efficient for validation pipelines. The resulting sequence is lazy and will only be evaluated when iterated.

Example:

// Parse a sequence of strings to integers
parse := func(s string) Option[int] {
    n, err := strconv.Atoi(s)
    if err != nil { return None[int]() }
    return Some(n)
}

// Create a sequence of strings
strings := func(yield func(string) bool) {
    for _, s := range []string{"1", "2", "3"} {
        if !yield(s) { return }
    }
}

result := TraverseIter(parse)(strings)
// result is Some(sequence of [1, 2, 3])

// With invalid input
invalidStrings := func(yield func(string) bool) {
    for _, s := range []string{"1", "invalid", "3"} {
        if !yield(s) { return }
    }
}

result := TraverseIter(parse)(invalidStrings)
// result is None because "invalid" cannot be parsed
Example

Example test demonstrating usage

// Parse a sequence of strings to integers
parse := func(s string) Option[int] {
	n, err := strconv.Atoi(s)
	if err != nil {
		return None[int]()
	}
	return Some(n)
}

// Create a sequence of valid strings
validStrings := seqFromSlice([]string{"1", "2", "3"})
result := TraverseIter(parse)(validStrings)

if IsSome(result) {
	numbers := MonadFold(result, func() []int { return nil }, collectSeq[int])
	fmt.Println(numbers)
}

// Create a sequence with invalid string
invalidStrings := seqFromSlice([]string{"1", "invalid", "3"})
result2 := TraverseIter(parse)(invalidStrings)

if IsNone(result2) {
	fmt.Println("Parsing failed")
}
Output:

[1 2 3]
Parsing failed

func TraverseRecord

func TraverseRecord[K comparable, A, B any](f Kleisli[A, B]) Kleisli[map[K]A, map[K]B]

TraverseRecord transforms a record (map) by applying a function that returns an Option to each value. Returns Some containing the map of results if all operations succeed, None if any fails.

Example:

validate := func(x int) Option[string] {
    if x > 0 { return Some(fmt.Sprintf("%d", x)) }
    return None[string]()
}
input := map[string]int{"a": 1, "b": 2}
result := TraverseRecord(validate)(input) // Some(map[a:"1" b:"2"])

func TraverseRecordG

func TraverseRecordG[GA ~map[K]A, GB ~map[K]B, K comparable, A, B any](f Kleisli[A, B]) Kleisli[GA, GB]

TraverseRecordG transforms a record (map) by applying a function that returns an Option to each value. Returns Some containing the map of results if all operations succeed, None if any fails. This is the generic version that works with custom map types.

Example:

validate := func(x int) Option[int] {
    if x > 0 { return Some(x * 2) }
    return None[int]()
}
input := map[string]int{"a": 1, "b": 2}
result := TraverseRecordG[map[string]int, map[string]int](validate)(input) // Some(map[a:2 b:4])

func TraverseRecordWithIndex

func TraverseRecordWithIndex[K comparable, A, B any](f func(K, A) Option[B]) Kleisli[map[K]A, map[K]B]

TraverseRecordWithIndex transforms a record by applying a function that receives both key and value. Returns Some containing the map of results if all operations succeed, None if any fails.

Example:

f := func(k string, v int) Option[int] {
    if v > 0 { return Some(v) }
    return None[int]()
}
input := map[string]int{"a": 1, "b": 2}
result := TraverseRecordWithIndex(f)(input) // Some(map[a:1 b:2])

func TraverseRecordWithIndexG

func TraverseRecordWithIndexG[GA ~map[K]A, GB ~map[K]B, K comparable, A, B any](f func(K, A) Option[B]) Kleisli[GA, GB]

TraverseRecordWithIndexG transforms a record by applying a function that receives both key and value. Returns Some containing the map of results if all operations succeed, None if any fails. This is the generic version that works with custom map types.

Example:

f := func(k string, v int) Option[string] {
    return Some(fmt.Sprintf("%s:%d", k, v))
}
input := map[string]int{"a": 1, "b": 2}
result := TraverseRecordWithIndexG[map[string]int, map[string]string](f)(input) // Some(map[a:"a:1" b:"b:2"])

type Operator

type Operator[A, B any] = Kleisli[Option[A], B]

func Alt

func Alt[A any](that func() Option[A]) Operator[A, A]

Alt returns a function that provides an alternative Option if the input is None.

Example:

withDefault := Alt(func() Option[int] { return Some(0) })
result := withDefault(Some(5)) // Some(5)
result := withDefault(None[int]()) // Some(0)

func Ap

func Ap[B, A any](fa Option[A]) Operator[func(A) B, B]

Ap is the curried applicative functor for Option. Returns a function that applies an Option-wrapped function to the given Option value.

Example:

fa := Some(5)
applyTo5 := Ap[int](fa)
fab := Some(N.Mul(2))
result := applyTo5(fab) // Some(10)

func ApS

func ApS[S1, S2, T any](
	setter func(T) func(S1) S2,
	fa Option[T],
) Operator[S1, S2]

ApS attaches a value to a context S1 to produce a context S2 by considering the context and the value concurrently. This uses the applicative functor pattern, allowing parallel composition.

Example:

type State struct { x int; y int }
result := F.Pipe2(
    Do(State{}),
    ApS(func(x int) func(State) State {
        return func(s State) State { s.x = x; return s }
    }, Some(42)),
)

func ApSL

func ApSL[S, T any](
	lens L.Lens[S, T],
	fa Option[T],
) Operator[S, S]

ApSL attaches a value to a context using a lens-based setter. This is a convenience function that combines ApS with a lens, allowing you to use optics to update nested structures in a more composable way.

The lens parameter provides both the getter and setter for a field within the structure S. This eliminates the need to manually write setter functions.

Example:

type Address struct {
    Street string
    City   string
}

type Person struct {
    Name    string
    Address Address
}

// Create a lens for the Address field
addressLens := lens.MakeLens(
    func(p Person) Address { return p.Address },
    func(p Person, a Address) Person { p.Address = a; return p },
)

// Use ApSL to update the address
result := F.Pipe2(
    option.Some(Person{Name: "Alice"}),
    option.ApSL(
        addressLens,
        option.Some(Address{Street: "Main St", City: "NYC"}),
    ),
)

func Bind

func Bind[S1, S2, A any](
	setter func(A) func(S1) S2,
	f Kleisli[S1, A],
) Operator[S1, S2]

Bind attaches the result of a computation to a context S1 to produce a context S2. This is used in do-notation style to sequentially build up a context.

Example:

type State struct { x int; y int }
result := F.Pipe2(
    Do(State{}),
    Bind(func(x int) func(State) State {
        return func(s State) State { s.x = x; return s }
    }, func(s State) Option[int] { return Some(42) }),
)

func BindL

func BindL[S, T any](
	lens L.Lens[S, T],
	f Kleisli[T, T],
) Operator[S, S]

BindL attaches the result of a computation to a context using a lens-based setter. This is a convenience function that combines Bind with a lens, allowing you to use optics to update nested structures based on their current values.

The lens parameter provides both the getter and setter for a field within the structure S. The computation function f receives the current value of the focused field and returns an Option that produces the new value.

Unlike ApSL, BindL uses monadic sequencing, meaning the computation f can depend on the current value of the focused field.

Example:

type Counter struct {
    Value int
}

valueLens := lens.MakeLens(
    func(c Counter) int { return c.Value },
    func(c Counter, v int) Counter { c.Value = v; return c },
)

// Increment the counter, but return None if it would exceed 100
increment := func(v int) option.Option[int] {
    if v >= 100 {
        return option.None[int]()
    }
    return option.Some(v + 1)
}

result := F.Pipe1(
    option.Some(Counter{Value: 42}),
    option.BindL(valueLens, increment),
) // Some(Counter{Value: 43})

func BindTo

func BindTo[S1, T any](
	setter func(T) S1,
) Operator[T, S1]

BindTo initializes a new state S1 from a value T. This is typically used as the first operation after creating an Option value.

Example:

type State struct { value int }
result := F.Pipe1(
    Some(42),
    BindTo(func(x int) State { return State{value: x} }),
)

func Chain

func Chain[A, B any](f Kleisli[A, B]) Operator[A, B]

Chain returns a function that applies an Option-returning function to an Option value. This is the curried form of the monadic bind operation.

Example:

validate := Chain(func(x int) Option[int] {
    if x > 0 { return Some(x * 2) }
    return None[int]()
})
result := validate(Some(5)) // Some(10)

func ChainFirst

func ChainFirst[A, B any](f Kleisli[A, B]) Operator[A, A]

ChainFirst returns a function that applies an Option-returning function but keeps the original value.

Example:

logAndKeep := ChainFirst(func(x int) Option[string] {
    fmt.Println(x)
    return Some("logged")
})
result := logAndKeep(Some(5)) // Some(5)

func ChainTo

func ChainTo[A, B any](mb Option[B]) Operator[A, B]

ChainTo returns a function that ignores its input Option and returns a fixed Option.

Example:

replaceWith := ChainTo(Some("hello"))
result := replaceWith(Some(42)) // Some("hello")

func Filter

func Filter[A any](pred func(A) bool) Operator[A, A]

Filter keeps the Option if it's Some and the predicate is satisfied, otherwise returns None.

Example:

isPositive := Filter(func(x int) bool { return x > 0 })
result := isPositive(Some(5)) // Some(5)
result := isPositive(Some(-1)) // None
result := isPositive(None[int]()) // None

func Flap

func Flap[B, A any](a A) Operator[func(A) B, B]

Flap returns a function that applies a value to an Option-wrapped function.

Example:

applyFive := Flap[int](5)
fab := Some(N.Mul(2))
result := applyFive(fab) // Some(10)

func Let

func Let[S1, S2, B any](
	key func(B) func(S1) S2,
	f func(S1) B,
) Operator[S1, S2]

Let attaches the result of a pure computation to a context S1 to produce a context S2. Unlike Bind, the computation function returns a plain value, not an Option.

Example:

type State struct { x int; computed int }
result := F.Pipe2(
    Do(State{x: 5}),
    Let(func(c int) func(State) State {
        return func(s State) State { s.computed = c; return s }
    }, func(s State) int { return s.x * 2 }),
)

func LetL

func LetL[S, T any](
	lens L.Lens[S, T],
	f Endomorphism[T],
) Operator[S, S]

LetL attaches the result of a pure computation to a context using a lens-based setter. This is a convenience function that combines Let with a lens, allowing you to use optics to update nested structures with pure transformations.

The lens parameter provides both the getter and setter for a field within the structure S. The transformation function f receives the current value of the focused field and returns the new value directly (not wrapped in Option).

This is useful for pure transformations that cannot fail, such as mathematical operations, string manipulations, or other deterministic updates.

Example:

type Counter struct {
    Value int
}

valueLens := lens.MakeLens(
    func(c Counter) int { return c.Value },
    func(c Counter, v int) Counter { c.Value = v; return c },
)

// Double the counter value
double := func(v int) int { return v * 2 }

result := F.Pipe1(
    option.Some(Counter{Value: 21}),
    option.LetL(valueLens, double),
) // Some(Counter{Value: 42})

func LetTo

func LetTo[S1, S2, B any](
	key func(B) func(S1) S2,
	b B,
) Operator[S1, S2]

LetTo attaches a constant value to a context S1 to produce a context S2.

Example:

type State struct { x int; name string }
result := F.Pipe2(
    Do(State{x: 5}),
    LetTo(func(n string) func(State) State {
        return func(s State) State { s.name = n; return s }
    }, "example"),
)

func LetToL

func LetToL[S, T any](
	lens L.Lens[S, T],
	b T,
) Operator[S, S]

LetToL attaches a constant value to a context using a lens-based setter. This is a convenience function that combines LetTo with a lens, allowing you to use optics to set nested fields to specific values.

The lens parameter provides the setter for a field within the structure S. Unlike LetL which transforms the current value, LetToL simply replaces it with the provided constant value b.

This is useful for resetting fields, initializing values, or setting fields to predetermined constants.

Example:

type Config struct {
    Debug   bool
    Timeout int
}

debugLens := lens.MakeLens(
    func(c Config) bool { return c.Debug },
    func(c Config, d bool) Config { c.Debug = d; return c },
)

result := F.Pipe1(
    option.Some(Config{Debug: true, Timeout: 30}),
    option.LetToL(debugLens, false),
) // Some(Config{Debug: false, Timeout: 30})

func Map

func Map[A, B any](f func(a A) B) Operator[A, B]

Map returns a function that applies a transformation to the value inside an Option. If the Option is None, returns None.

Example:

double := Map(N.Mul(2))
result := double(Some(5)) // Some(10)
result := double(None[int]()) // None

func MapTo

func MapTo[A, B any](b B) Operator[A, B]

MapTo returns a function that replaces the value inside an Option with a constant.

Example:

replaceWith42 := MapTo[string, int](42)
result := replaceWith42(Some("hello")) // Some(42)

type Option

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

Option defines a data structure that logically holds a value or not. It represents an optional value: every Option is either Some and contains a value, or None, and does not contain a value.

Option is commonly used to represent the result of operations that may fail, as an alternative to returning nil pointers or using error values.

Example:

var opt Option[int] = Some(42)  // Contains a value
var opt Option[int] = None[int]() // Contains no value
Example (Creation)
// Build an Option
none1 := None[int]()
some1 := Some("value")

// Build from a value
fromNillable := FromNillable[string]
nonFromNil := fromNillable(nil) // None[*string]
value := "value"
someFromPointer := fromNillable(&value) // Some[*string](xxx)

// some predicate
isEven := func(num int) bool {
	return num%2 == 0
}

fromEven := FromPredicate(isEven)
noneFromPred := fromEven(3) // None[int]
someFromPred := fromEven(4) // Some[int](4)

fmt.Println(none1)
fmt.Println(some1)
fmt.Println(nonFromNil)
fmt.Println(IsSome(someFromPointer))
fmt.Println(noneFromPred)
fmt.Println(someFromPred)
Output:

None[int]
Some[string](value)
None[string]
true
None[int]
Some[int](4)
Example (Extraction)
noneValue := None[int]()
someValue := Of(42)

// Convert Option[T] to T
fromNone, okFromNone := Unwrap(noneValue) // 0, false
fromSome, okFromSome := Unwrap(someValue) // 42, true

// Convert Option[T] with a default value
noneWithDefault := GetOrElse(F.Constant(0))(noneValue) // 0
someWithDefault := GetOrElse(F.Constant(0))(someValue) // 42

// Apply a different function on None/Some(...)
doubleOrZero := Fold(
	F.Constant(0), // none case
	N.Mul(2),      // some case
) // func(ma Option[int]) int

doubleFromNone := doubleOrZero(noneValue) // 0
doubleFromSome := doubleOrZero(someValue) // 84

// Pro-tip: Fold is short for the following:
doubleOfZeroBis := F.Flow2(
	Map(N.Mul(2)),            // some case
	GetOrElse(F.Constant(0)), // none case
)
doubleFromNoneBis := doubleOfZeroBis(noneValue) // 0
doubleFromSomeBis := doubleOfZeroBis(someValue) // 84

fmt.Printf("%d, %t\n", fromNone, okFromNone)
fmt.Printf("%d, %t\n", fromSome, okFromSome)
fmt.Println(noneWithDefault)
fmt.Println(someWithDefault)
fmt.Println(doubleFromNone)
fmt.Println(doubleFromSome)
fmt.Println(doubleFromNoneBis)
fmt.Println(doubleFromSomeBis)
Output:

0, false
42, true
0
42
0
84
0
84
Example (Formatting_comparison)

ExampleOption_formatting_comparison demonstrates different formatting options.

package main

import (
	"fmt"

	O "github.com/IBM/fp-go/v2/option"
)

func main() {
	type User struct {
		ID   int
		Name string
	}

	user := User{ID: 123, Name: "Alice"}
	result := O.Some(user)

	fmt.Printf("String():   %s\n", result.String())
	fmt.Printf("GoString(): %s\n", result.GoString())
	fmt.Printf("%%v:         %v\n", result)
	fmt.Printf("%%#v:        %#v\n", result)

}
Output:

String():   Some[option_test.User]({123 Alice})
GoString(): option.Some[option_test.User](option_test.User{ID:123, Name:"Alice"})
%v:         Some[option_test.User]({123 Alice})
%#v:        option.Some[option_test.User](option_test.User{ID:123, Name:"Alice"})

func Do

func Do[S any](
	empty S,
) Option[S]

Do creates an empty context of type S to be used with the Bind operation. This is the starting point for building up a context using do-notation style.

Example:

type Result struct {
    x int
    y string
}
result := Do(Result{})

func Flatten

func Flatten[A any](mma Option[Option[A]]) Option[A]

Flatten removes one level of nesting from a nested Option.

Example:

nested := Some(Some(42))
result := Flatten(nested) // Some(42)
nested := Some(None[int]())
result := Flatten(nested) // None

func FromNillable

func FromNillable[A any](a *A) Option[*A]

FromNillable converts a pointer to an Option. Returns Some if the pointer is non-nil, None otherwise.

Example:

var ptr *int = nil
result := FromNillable(ptr) // None
val := 42
result := FromNillable(&val) // Some(&val)

func MonadAlt

func MonadAlt[A any](fa Option[A], that func() Option[A]) Option[A]

MonadAlt returns the first Option if it's Some, otherwise returns the alternative. This is the monadic form of the Alt operation.

Example:

result := MonadAlt(Some(5), func() Option[int] { return Some(10) }) // Some(5)
result := MonadAlt(None[int](), func() Option[int] { return Some(10) }) // Some(10)

func MonadAp

func MonadAp[B, A any](fab Option[func(A) B], fa Option[A]) Option[B]

MonadAp applies a function wrapped in an Option to a value wrapped in an Option. If either the function or the value is None, returns None. This is the monadic form of the applicative functor.

Example:

fab := Some(N.Mul(2))
fa := Some(5)
result := MonadAp(fab, fa) // Some(10)

func MonadChain

func MonadChain[A, B any](fa Option[A], f Kleisli[A, B]) Option[B]

MonadChain applies a function that returns an Option to the value inside an Option. This is the monadic bind operation. If the input is None, returns None.

Example:

fa := Some(5)
result := MonadChain(fa, func(x int) Option[int] {
    if x > 0 { return Some(x * 2) }
    return None[int]()
}) // Some(10)

func MonadChainFirst

func MonadChainFirst[A, B any](ma Option[A], f Kleisli[A, B]) Option[A]

MonadChainFirst applies a function that returns an Option but keeps the original value. If either operation results in None, returns None.

Example:

result := MonadChainFirst(Some(5), func(x int) Option[string] {
    return Some(fmt.Sprintf("%d", x))
}) // Some(5) - original value is kept

func MonadChainTo

func MonadChainTo[A, B any](ma Option[A], mb Option[B]) Option[B]

MonadChainTo ignores the first Option and returns the second Option. Useful for sequencing operations where the first result is not needed.

Example:

result := MonadChainTo(Some(5), Some("hello")) // Some("hello")

func MonadFlap

func MonadFlap[B, A any](fab Option[func(A) B], a A) Option[B]

MonadFlap applies a value to a function wrapped in an Option. This is the monadic form of Flap.

Example:

fab := Some(N.Mul(2))
result := MonadFlap(fab, 5) // Some(10)

func MonadMap

func MonadMap[A, B any](fa Option[A], f func(A) B) Option[B]

MonadMap applies a function to the value inside an Option. If the Option is None, returns None. This is the monadic form of Map.

Example:

fa := Some(5)
result := MonadMap(fa, N.Mul(2)) // Some(10)

func MonadMapTo

func MonadMapTo[A, B any](fa Option[A], b B) Option[B]

MonadMapTo replaces the value inside an Option with a constant value. If the Option is None, returns None. This is the monadic form of MapTo.

Example:

fa := Some(5)
result := MonadMapTo(fa, "hello") // Some("hello")

func MonadSequence2

func MonadSequence2[T1, T2, R any](o1 Option[T1], o2 Option[T2], f func(T1, T2) Option[R]) Option[R]

MonadSequence2 sequences two Options and applies a function to their values. Returns None if either Option is None.

Example:

result := MonadSequence2(Some(2), Some(3), func(a, b int) Option[int] {
    return Some(a + b)
}) // Some(5)

func None

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

None creates an Option that contains no value.

Example:

opt := None[int]() // Empty Option of type int
opt := None[string]() // Empty Option of type string

func Of

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

Of creates an Option that contains a value. This is an alias for Some and is used in monadic contexts.

Example:

opt := Of(42) // Option containing 42

func SequenceArray

func SequenceArray[A any](ma []Option[A]) Option[[]A]

SequenceArray converts an array of Options into an Option of an array. Returns Some containing all values if all Options are Some, None if any is None.

Example:

result := SequenceArray([]Option[int]{Some(1), Some(2), Some(3)}) // Some([1, 2, 3])
result := SequenceArray([]Option[int]{Some(1), None[int](), Some(3)}) // None

func SequenceArrayG

func SequenceArrayG[GA ~[]A, GOA ~[]Option[A], A any](ma GOA) Option[GA]

SequenceArrayG converts an array of Options into an Option of an array. Returns Some containing all values if all Options are Some, None if any is None. This is the generic version that works with custom slice types.

Example:

type MySlice []int
result := SequenceArrayG[MySlice]([]Option[int]{Some(1), Some(2)}) // Some(MySlice{1, 2})
result := SequenceArrayG[MySlice]([]Option[int]{Some(1), None[int]()}) // None

func SequenceIter

func SequenceIter[A any](as Seq[Option[A]]) Option[Seq[A]]

func SequencePair

func SequencePair[T1, T2 any](t P.Pair[Option[T1], Option[T2]]) Option[P.Pair[T1, T2]]

SequencePair converts a Pair of Options into an Option of a Pair. Returns Some containing the pair of values if both Options are Some, None if either is None.

Example:

pair := P.MakePair(Some(1), Some("hello"))
result := SequencePair(pair) // Some(Pair(1, "hello"))

pair := P.MakePair(Some(1), None[string]())
result := SequencePair(pair) // None

func SequenceRecord

func SequenceRecord[K comparable, A any](ma map[K]Option[A]) Option[map[K]A]

SequenceRecord converts a map of Options into an Option of a map. Returns Some containing all key-value pairs if all Options are Some, None if any is None.

Example:

input := map[string]Option[int]{"a": Some(1), "b": Some(2), "c": Some(3)}
result := SequenceRecord(input) // Some(map[a:1 b:2 c:3])
input := map[string]Option[int]{"a": Some(1), "b": None[int]()}
result := SequenceRecord(input) // None

func SequenceRecordG

func SequenceRecordG[GA ~map[K]A, GOA ~map[K]Option[A], K comparable, A any](ma GOA) Option[GA]

SequenceRecordG converts a map of Options into an Option of a map. Returns Some containing all key-value pairs if all Options are Some, None if any is None. This is the generic version that works with custom map types.

Example:

type MyMap map[string]int
input := map[string]Option[int]{"a": Some(1), "b": Some(2)}
result := SequenceRecordG[MyMap](input) // Some(MyMap{"a": 1, "b": 2})

func SequenceT1

func SequenceT1[T1 any](t1 Option[T1]) Option[T.Tuple1[T1]]

SequenceT1 converts 1 parameters of [Option[T]] into a [Option[Tuple1]].

func SequenceT10

func SequenceT10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t1 Option[T1], t2 Option[T2], t3 Option[T3], t4 Option[T4], t5 Option[T5], t6 Option[T6], t7 Option[T7], t8 Option[T8], t9 Option[T9], t10 Option[T10]) Option[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]

SequenceT10 converts 10 parameters of [Option[T]] into a [Option[Tuple10]].

func SequenceT2

func SequenceT2[T1, T2 any](t1 Option[T1], t2 Option[T2]) Option[T.Tuple2[T1, T2]]

SequenceT2 converts 2 parameters of [Option[T]] into a [Option[Tuple2]].

func SequenceT3

func SequenceT3[T1, T2, T3 any](t1 Option[T1], t2 Option[T2], t3 Option[T3]) Option[T.Tuple3[T1, T2, T3]]

SequenceT3 converts 3 parameters of [Option[T]] into a [Option[Tuple3]].

func SequenceT4

func SequenceT4[T1, T2, T3, T4 any](t1 Option[T1], t2 Option[T2], t3 Option[T3], t4 Option[T4]) Option[T.Tuple4[T1, T2, T3, T4]]

SequenceT4 converts 4 parameters of [Option[T]] into a [Option[Tuple4]].

func SequenceT5

func SequenceT5[T1, T2, T3, T4, T5 any](t1 Option[T1], t2 Option[T2], t3 Option[T3], t4 Option[T4], t5 Option[T5]) Option[T.Tuple5[T1, T2, T3, T4, T5]]

SequenceT5 converts 5 parameters of [Option[T]] into a [Option[Tuple5]].

func SequenceT6

func SequenceT6[T1, T2, T3, T4, T5, T6 any](t1 Option[T1], t2 Option[T2], t3 Option[T3], t4 Option[T4], t5 Option[T5], t6 Option[T6]) Option[T.Tuple6[T1, T2, T3, T4, T5, T6]]

SequenceT6 converts 6 parameters of [Option[T]] into a [Option[Tuple6]].

func SequenceT7

func SequenceT7[T1, T2, T3, T4, T5, T6, T7 any](t1 Option[T1], t2 Option[T2], t3 Option[T3], t4 Option[T4], t5 Option[T5], t6 Option[T6], t7 Option[T7]) Option[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]]

SequenceT7 converts 7 parameters of [Option[T]] into a [Option[Tuple7]].

func SequenceT8

func SequenceT8[T1, T2, T3, T4, T5, T6, T7, T8 any](t1 Option[T1], t2 Option[T2], t3 Option[T3], t4 Option[T4], t5 Option[T5], t6 Option[T6], t7 Option[T7], t8 Option[T8]) Option[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]

SequenceT8 converts 8 parameters of [Option[T]] into a [Option[Tuple8]].

func SequenceT9

func SequenceT9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t1 Option[T1], t2 Option[T2], t3 Option[T3], t4 Option[T4], t5 Option[T5], t6 Option[T6], t7 Option[T7], t8 Option[T8], t9 Option[T9]) Option[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]

SequenceT9 converts 9 parameters of [Option[T]] into a [Option[Tuple9]].

func SequenceTuple1

func SequenceTuple1[T1 any](t T.Tuple1[Option[T1]]) Option[T.Tuple1[T1]]

SequenceTuple1 converts a [Tuple1] of [Option[T]] into an [Option[Tuple1]].

func SequenceTuple10

func SequenceTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](t T.Tuple10[Option[T1], Option[T2], Option[T3], Option[T4], Option[T5], Option[T6], Option[T7], Option[T8], Option[T9], Option[T10]]) Option[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]

SequenceTuple10 converts a [Tuple10] of [Option[T]] into an [Option[Tuple10]].

func SequenceTuple2

func SequenceTuple2[T1, T2 any](t T.Tuple2[Option[T1], Option[T2]]) Option[T.Tuple2[T1, T2]]

SequenceTuple2 converts a [Tuple2] of [Option[T]] into an [Option[Tuple2]].

func SequenceTuple3

func SequenceTuple3[T1, T2, T3 any](t T.Tuple3[Option[T1], Option[T2], Option[T3]]) Option[T.Tuple3[T1, T2, T3]]

SequenceTuple3 converts a [Tuple3] of [Option[T]] into an [Option[Tuple3]].

func SequenceTuple4

func SequenceTuple4[T1, T2, T3, T4 any](t T.Tuple4[Option[T1], Option[T2], Option[T3], Option[T4]]) Option[T.Tuple4[T1, T2, T3, T4]]

SequenceTuple4 converts a [Tuple4] of [Option[T]] into an [Option[Tuple4]].

func SequenceTuple5

func SequenceTuple5[T1, T2, T3, T4, T5 any](t T.Tuple5[Option[T1], Option[T2], Option[T3], Option[T4], Option[T5]]) Option[T.Tuple5[T1, T2, T3, T4, T5]]

SequenceTuple5 converts a [Tuple5] of [Option[T]] into an [Option[Tuple5]].

func SequenceTuple6

func SequenceTuple6[T1, T2, T3, T4, T5, T6 any](t T.Tuple6[Option[T1], Option[T2], Option[T3], Option[T4], Option[T5], Option[T6]]) Option[T.Tuple6[T1, T2, T3, T4, T5, T6]]

SequenceTuple6 converts a [Tuple6] of [Option[T]] into an [Option[Tuple6]].

func SequenceTuple7

func SequenceTuple7[T1, T2, T3, T4, T5, T6, T7 any](t T.Tuple7[Option[T1], Option[T2], Option[T3], Option[T4], Option[T5], Option[T6], Option[T7]]) Option[T.Tuple7[T1, T2, T3, T4, T5, T6, T7]]

SequenceTuple7 converts a [Tuple7] of [Option[T]] into an [Option[Tuple7]].

func SequenceTuple8

func SequenceTuple8[T1, T2, T3, T4, T5, T6, T7, T8 any](t T.Tuple8[Option[T1], Option[T2], Option[T3], Option[T4], Option[T5], Option[T6], Option[T7], Option[T8]]) Option[T.Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]

SequenceTuple8 converts a [Tuple8] of [Option[T]] into an [Option[Tuple8]].

func SequenceTuple9

func SequenceTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](t T.Tuple9[Option[T1], Option[T2], Option[T3], Option[T4], Option[T5], Option[T6], Option[T7], Option[T8], Option[T9]]) Option[T.Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]

SequenceTuple9 converts a [Tuple9] of [Option[T]] into an [Option[Tuple9]].

func Some

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

Some creates an Option that contains a value.

Example:

opt := Some(42) // Option containing 42
opt := Some("hello") // Option containing "hello"

func ToAny

func ToAny[T any](src T) Option[any]

ToAny converts a value of any type to Option[any]. This always succeeds and returns Some containing the value as any.

Example:

result := ToAny(42) // Some(any(42))
result := ToAny("hello") // Some(any("hello"))

func ToType

func ToType[T any](src any) Option[T]

ToType attempts to convert a value of type any to a specific type T using type assertion. Returns Some(value) if the type assertion succeeds, None if it fails.

Example:

var x any = 42
result := ToType[int](x) // Some(42)

var y any = "hello"
result := ToType[int](y) // None (wrong type)

func TryCatch

func TryCatch[A any](f func() (A, error)) Option[A]

TryCatch executes a function that may return an error and converts the result to an Option. Returns Some(value) if no error occurred, None if an error occurred.

Example:

result := TryCatch(func() (int, error) {
    return strconv.Atoi("42")
}) // Some(42)

func (Option[A]) Format

func (s Option[A]) Format(f fmt.State, c rune)

Format implements fmt.Formatter for Option. Supports all standard format verbs:

  • %s, %v, %+v: uses String() representation
  • %#v: uses GoString() representation
  • %q: quoted String() representation
  • other verbs: uses String() representation

Example:

opt := Some(42)
fmt.Printf("%s", opt)   // "Some[int](42)"
fmt.Printf("%v", opt)   // "Some[int](42)"
fmt.Printf("%#v", opt)  // "option.Some[int](42)"
Example

ExampleOption_Format demonstrates the fmt.Formatter interface implementation.

package main

import (
	"fmt"

	O "github.com/IBM/fp-go/v2/option"
)

func main() {
	result := O.Some(42)

	// Different format verbs
	fmt.Printf("%%s: %s\n", result)
	fmt.Printf("%%v: %v\n", result)
	fmt.Printf("%%+v: %+v\n", result)
	fmt.Printf("%%#v: %#v\n", result)

}
Output:

%s: Some[int](42)
%v: Some[int](42)
%+v: Some[int](42)
%#v: option.Some[int](42)

func (Option[A]) GoString

func (s Option[A]) GoString() string

GoString implements fmt.GoStringer for Option. Returns a Go-syntax representation of the Option value.

Example:

Some(42).GoString() // "option.Some[int](42)"
None[int]().GoString() // "option.None[int]()"
Example

ExampleOption_GoString demonstrates the fmt.GoStringer interface implementation.

package main

import (
	"fmt"

	O "github.com/IBM/fp-go/v2/option"
)

func main() {
	some := O.Some(42)
	none := O.None[int]()

	fmt.Printf("%#v\n", some)
	fmt.Printf("%#v\n", none)

}
Output:

option.Some[int](42)
option.None[int]

func (Option[A]) LogValue

func (s Option[A]) LogValue() slog.Value

LogValue implements slog.LogValuer for Option. Returns a slog.Value that represents the Option for structured logging. Returns a group value with "some" key for Some values and "none" key for None values.

Example:

logger := slog.Default()
result := Some(42)
logger.Info("result", "value", result)
// Logs: {"msg":"result","value":{"some":42}}

empty := None[int]()
logger.Info("empty", "value", empty)
// Logs: {"msg":"empty","value":{"none":{}}}
Example

ExampleOption_LogValue demonstrates the slog.LogValuer interface implementation.

package main

import (
	"log/slog"
	"os"

	O "github.com/IBM/fp-go/v2/option"
)

func main() {
	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
		Level: slog.LevelInfo,
		ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
			// Remove time for consistent output
			if a.Key == slog.TimeKey {
				return slog.Attr{}
			}
			return a
		},
	}))

	// Some value
	someResult := O.Some(42)
	logger.Info("computation succeeded", "result", someResult)

	// None value
	noneResult := O.None[int]()
	logger.Info("computation failed", "result", noneResult)

}
Output:

level=INFO msg="computation succeeded" result.some=42
level=INFO msg="computation failed" result.none={}
Example (Structured)

ExampleOption_LogValue_structured demonstrates structured logging with Option.

package main

import (
	"log/slog"
	"os"

	O "github.com/IBM/fp-go/v2/option"
)

func main() {
	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
		Level: slog.LevelInfo,
		ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
			if a.Key == slog.TimeKey {
				return slog.Attr{}
			}
			return a
		},
	}))

	// Simulate a computation pipeline
	compute := func(x int) O.Option[int] {
		if x < 0 {
			return O.None[int]()
		}
		return O.Some(x * 2)
	}

	// Log successful computation
	result1 := compute(21)
	logger.Info("computation", "input", 21, "output", result1)

	// Log failed computation
	result2 := compute(-5)
	logger.Warn("computation", "input", -5, "output", result2)

}
Output:

level=INFO msg=computation input=21 output.some=42
level=WARN msg=computation input=-5 output.none={}

func (Option[A]) MarshalJSON

func (s Option[A]) MarshalJSON() ([]byte, error)

func (Option[A]) String

func (s Option[A]) String() string

String implements fmt.Stringer for Option. Returns a human-readable string representation.

Example:

Some(42).String() // "Some[int](42)"
None[int]().String() // "None[int]"
Example

ExampleOption_String demonstrates the fmt.Stringer interface implementation.

package main

import (
	"fmt"

	O "github.com/IBM/fp-go/v2/option"
)

func main() {
	some := O.Some(42)
	none := O.None[int]()

	fmt.Println(some.String())
	fmt.Println(none.String())

}
Output:

Some[int](42)
None[int]

func (*Option[A]) UnmarshalJSON

func (s *Option[A]) UnmarshalJSON(data []byte) error

type Seq

type Seq[T any] = iter.Seq[T]

Directories

Path Synopsis
Package number provides Option-based utilities for number conversions.
Package number provides Option-based utilities for number conversions.

Jump to

Keyboard shortcuts

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