gofp

package module
v0.1.3 Latest Latest
Warning

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

Go to latest
Published: Feb 21, 2026 License: MIT Imports: 4 Imported by: 0

README

gofp

Gofp is a Rust inspired functional primitives library for Go. It's bringing type-safe `Result`, `Option`, and `Either` types with zero allocations and composable error handling.


Why

Go's if err != nil pattern is honest and explicit. But it doesn't compose. You can't chain transformations, propagate errors through a pipeline or express "this value might not exist" in the type system.

gofp fills that gap not by hiding errors but by making them first-class values you can map, chain, and transform.

Install

go get github.com/Alsond5/gofp

Requires Go 1.23+.

Packages

Package Description
gofp Result[T], Option[T], Unit
gofp/result Map, AndThen, AllOf, Partition, FirstOk Result transformations and combinators
gofp/option Map, AndThen, Zip, Match Option transformations and combinators
gofp/either Either[L,R] two-outcome type for domain branching
gofp/must Panic helpers for initialization

Result[T]

Represents either a successful value (Ok) or an error (Err). Drop-in replacement for Go's (T, error) pattern.

// Construct
r := gofp.Ok(42)
r := gofp.Err[int](errors.New("something went wrong"))
r := gofp.Of(strconv.Atoi("42"))        // bridges (T, error) → Result[T]

// Check
r.IsOk()
r.IsErr()

// Unwrap
r.Unwrap()                              // panics on Err
r.UnwrapOr(0)                           // fallback value
r.UnwrapOrElse(func(err error) int { return -1 })

// Transform — free functions, type-safe T→U
result.Map(r, func(n int) string { return strconv.Itoa(n) })    // Result[string]
result.AndThen(r, func(n int) gofp.Result[string] { ... })      // Result[string]

// Chain multiple Results
result.AndThen(
    result.AndThen(parse(s), validate),
    process,
)

// Side effects
r.IfOk(func(n int) { log.Println(n) }).
    IfErr(func(err error) { log.Println(err) })

// Combine
result.AllOf(r1, r2, r3)                 // Result[[]T] — first Err wins
result.All2(r1, r2)                      // Result[Pair[A, B]]
result.Partition(results...)             // ([]T, []error)
result.FirstOk(r1, r2, r3)               // first Ok, or all errors joined

Try — Go's answer to ?

func handle(s string) gofp.Result[string] {
    return gofp.Try(func() string {
        age := parse(s).Unwrap()        // Err → caught by Try
        age  = validate(age).Unwrap()   // Err → caught by Try
        return format(age).Unwrap()     // Err → caught by Try
    })
    // real panics (nil pointer, index out of range) are re-panicked
}

Option[T]

Represents a value that may or may not exist. Replaces nil checks and pointer abuse.

// Construct
o := gofp.Some(42)
o := gofp.None[int]()
o := gofp.FromPtr(ptr)                  // nil ptr → None
o := gofp.FromZero(val)                 // zero value → None

// Check
o.IsSome()
o.IsNone()

// Unwrap
o.Unwrap()                              // panics on None
o.UnwrapOr(0)
o.UnwrapOrElse(func() int { return compute() })
o.UnwrapOrZero()                        // returns zero value

// Transform
o.Filter(func(n int) bool { return n > 0 })

option.Map(o, func(n int) string { ... })   // Option[string]
option.AndThen(func(n int) gofp.Option[string] { ... })

// Boolean combinators
o.Or(other)        // first Some
o.Xor(other)       // Some only if exactly one is Some
option.And(other)  // Some only if both Some

// Pair operations
option.Zip(a, b)                    // Option[Pair[A, B]]
option.ZipWith(a, b, func(x, y) z)  // Option[Z]

// Side effects
o.IfSome(func(n int) { ... }).
 IfNone(func() { ... })

o.Match(
    func(n int) { ... },                // Some branch
    func() { ... },                     // None branch
)

// Convert to Result
o.OkOr(ErrNotFound)
o.OkOrElse(func() error { return ErrNotFound })

Either[L, R]

A value that is either Left(L) or Right(R). Unlike Result, neither side implies failure both are valid domain values.

// Construct
e := either.Left[int, string](42)
e := either.Right[int, string]("guest")

// Check
e.IsLeft()
e.IsRight()

// Fold — primary way to consume an Either
msg := either.Fold(e,
    func(n int) string { return fmt.Sprintf("number: %d", n) },
    func(s string) string { return "string: " + s },
)

// Transform
either.MapLeft(e, func(n int) int { return n * 2 })
either.MapRight(e, func(s string) string { return strings.ToUpper(s) })
either.MapBoth(e, leftFn, rightFn)

// Side effects
e.IfLeft(func(n int) { log.Println(n) }).
 IfRight(func(s string) { log.Println(s) })

// Swap sides
e.Swap()                                // Either[R, L]

// Partition a slice
lefts, rights := either.Partition(eithers)

// Merge when both sides are the same type
either.Merge(either.Left[int, int](42)) // → 42

TryCatch — Try with two return types

e := either.TryCatch(
    func() int {                        // try  → Left on success
        age := parse(s).Unwrap()
        return validate(age).Unwrap()
    },
    func(err error) string {            // catch → Right on error
        return "invalid: " + err.Error()
    },
)
// Either[int, string]

either.Fold(e,
    func(age int) { fmt.Println("age:", age) },
    func(msg string) { fmt.Println("error:", msg) },
)

Real panics (nil pointer, index out of range) are re-panicked, not swallowed.

must

Panic helpers for program initialization. Not for request handling.

import "github.com/Alsond5/gofp/must"

// stdlib bridge
db := must.Do(sql.Open("postgres", dsn))

// invariants
must.Be(port > 0 && port < 65536, "invalid port")
must.Bef(len(items) > 0, "expected at least %d items, got %d", 1, len(items))

// environment
dsn  := must.Env("DATABASE_URL")           // panics if missing
port := must.EnvIntOr("PORT", 8080)        // fallback, panics if set but invalid

// parsing
re   := must.Regexp(`^[^@]+@[^@]+\.[^@]+$`)
tmpl := must.Template(template.ParseFiles("email.html"))

// nil safety
cfg := must.NotNil(loadConfig(), "config must not be nil")

// collection access
first := must.Index(items, 0, "items is empty")
val   := must.Key(m, "key", "missing required key")

// unreachable
default: must.Never("unhandled case")

Example

var ErrNotFound = errors.New("user not found")

type User struct {
    Name  string
    Email string
}

func findUser(db map[int]User, id int) gofp.Result[User] {
    user, ok := db[id]
    if !ok {
        return gofp.Err[User](ErrNotFound)
    }
    return gofp.Ok(user)
}

func greet(user User) string {
    return "Hello, " + user.Name + "!"
}

func main() {
    db := map[int]User{
        1: {Name: "Alice", Email: "alice@admin.com"},
    }

    result.Map(findUser(db, 1), greet).
        IfOk(func(msg string) { fmt.Println(msg) }).
        IfErr(func(err error) { fmt.Println("Error:", err) })

    // Output:
    // Hello, Alice!
}

Design Decisions

Why ok bool in structs? Go structs always have a zero value. Without an explicit flag, Result[int]{} and Ok(0) are structurally identical indistinguishable. The ok/some field makes the zero value explicitly invalid.

Why value receivers is not pointer receivers? Value receivers keep Result[T] and Option[T] on the stack. Pointer receivers cause heap allocation via escape analysis. For types used in hot paths, this matters.

Why free functions for Map, AndThen etc. ? Go methods cannot introduce new type parameters. func (r Result[T]) Map[U](f func(T) U) Result[U] is illegal. Free functions are the only type-safe way to express T → U transformations.

Why not pipe? A type-safe heterogeneous pipeline (T → U → V) requires methods that introduce new type parameters which Go doesn't allow. T → T pipes exist but add little over plain function calls. AndThen chains cover the real use cases.

License

gofp is licensed under the MIT License.

Documentation

Overview

Package gofp provides Rust-inspired functional primitives for Go.

gofp brings type-safe error handling and optional values to Go through three core types: Result, Option, and [Either]. All types are designed for zero heap allocation, full type safety, and composable pipelines.

Core Types

Result[T] represents a computation that either succeeds with a value of type T, or fails with an error:

r := gofp.Of(strconv.Atoi("42"))   // Result[int]
r.IfOk(func(n int) { fmt.Println(n) }).
	IfErr(func(err error) { fmt.Println(err) })

Option[T] represents a value that may or may not exist, replacing nil pointer patterns with an explicit type:

o := gofp.FromPtr(ptr)             // Option[T]
o.IfSome(func(v T) { ... }).
	IfNone(func() { ... })

Either[L, R] represents a value that is one of two possible types. Unlike Result, neither side implies failure both are valid domain values. See the either sub-package for constructors and operations.

Error Handling

gofp provides two approaches for propagating errors through a call chain.

FlatMap composes functions that return Result, short-circuiting on the first error:

gofp.FlatMap(
    gofp.FlatMap(parse(s), validate),
    process,
)

Try runs a function and recovers from Result panics, similar to Rust's ? operator. Only panics originating from Result.Unwrap are caught — real bugs are re-panicked:

result := gofp.Try(func() string {
    age  := parse(s).Unwrap()      // Err → caught
    age   = validate(age).Unwrap() // Err → caught
    return format(age).Unwrap()    // Err → caught
})

Sub-packages

Transformations that change the type parameter (T → U) cannot be expressed as methods in Go. These are provided as free functions in dedicated sub-packages:

Performance

Result[T] and Option[T] are plain structs no interfaces, no heap allocation. Value receivers ensure values stay on the stack. The ok and some boolean fields solve Go's zero value ambiguity without runtime overhead, as all accessor methods are inlined by the compiler.

Design Decisions

Methods are limited to transformations that preserve the type parameter (T → T). Transformations that change the type (T → U) are free functions in sub-packages, as Go does not allow methods to introduce new type parameters.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func TryCatch

func TryCatch[L, R any](try func() L, catch func(error) R) (e either.Either[L, R])

TryCatch runs try and recovers from Result panics. On success, returns Left(try()). On gofp panic, calls catch and returns Right(catch(err)). Real panics are re-panicked — not swallowed.

either.TryCatch(
    func() int { return parse(s).Unwrap() },
    func(err error) string { return err.Error() },
)

Types

type Option

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

Option[T] represents either a value of type T (Some) or no value (None).

Zero value is NOT valid. Always use Some(), None(), or constructor functions.

Option is immutable by design: all transformation methods return a new Option.

func FromPtr

func FromPtr[T any](ptr *T) Option[T]

FromPtr converts a pointer to an Option. If ptr is nil, returns None. Otherwise returns Some(*ptr). This is the primary bridge from legacy *T code to Option[T].

var p *User = db.FindUser(id)
o := gofp.FromPtr(p) // Option[User]

func FromZero

func FromZero[T comparable](value T) Option[T]

FromZero returns None if value equals the zero value of T, otherwise returns Some(value).

Useful for converting bare int/string/etc returns where zero means "absent". Use with caution: zero is a valid value in many domains.

gofp.FromZero(0)    // None[int]
gofp.FromZero(42)   // Some(42)
gofp.FromZero("")   // None[string]

func None

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

None returns an empty Option of type T.

o := gofp.None[int]()
o := gofp.None[User]()

func Some

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

Some returns an Option containing value.

o := gofp.Some(42)
o := gofp.Some(user)

func (Option[T]) Expect

func (o Option[T]) Expect(msg string) T

Expect returns the contained value. Panics with msg if the Option is None. Prefer over Unwrap when you want a meaningful panic message.

user := o.Expect("user must exist after authentication")

func (Option[T]) Filter

func (o Option[T]) Filter(f func(T) bool) Option[T]

Filter returns the Option unchanged if Some and f(value) is true. Returns None if the Option is None or f(value) is false.

even := gofp.Some(4).Filter(func(n int) bool { return n%2 == 0 }) // Some(4)
odd  := gofp.Some(3).Filter(func(n int) bool { return n%2 == 0 }) // None

func (Option[T]) IfNone

func (o Option[T]) IfNone(f func()) Option[T]

IfNone calls f if the Option is None. Returns the original Option unchanged for chaining.

o.IfNone(func() { log.Println("not found") })

func (Option[T]) IfSome

func (o Option[T]) IfSome(f func(T)) Option[T]

IfSome calls f with the contained value if Some. Returns the original Option unchanged for chaining.

o.IfSome(func(u User) { log.Println("found:", u.Name) })

func (Option[T]) Inspect

func (o Option[T]) Inspect(f func(T)) Option[T]

Inspect calls f with the contained value if Some, then returns the Option unchanged. Useful for debugging in a chain without breaking it.

o.Inspect(func(v int) { log.Println("got:", v) }).UnwrapOr(0)

func (Option[T]) IsNone

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

IsNone reports whether the Option contains no value.

if o.IsNone() { ... }

func (Option[T]) IsNoneOr

func (o Option[T]) IsNoneOr(f func(T) bool) bool

IsNoneOr returns true if the Option is None, or if it contains a value and f(value) returns true.

gofp.None[int]().IsNoneOr(func(n int) bool { return n > 0 })  // true
gofp.Some(42).IsNoneOr(func(n int) bool { return n > 0 })     // true
gofp.Some(-1).IsNoneOr(func(n int) bool { return n > 0 })     // false

func (Option[T]) IsSome

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

IsSome reports whether the Option contains a value.

if o.IsSome() { ... }

func (Option[T]) IsSomeAnd

func (o Option[T]) IsSomeAnd(f func(T) bool) bool

IsSomeAnd returns true if the Option contains a value and f(value) returns true. Returns false for None without calling f.

gofp.Some(42).IsSomeAnd(func(n int) bool { return n > 0 })    // true
gofp.None[int]().IsSomeAnd(func(n int) bool { return true })	// false

func (Option[T]) Match

func (o Option[T]) Match(someFn func(T), noneFn func())

Match calls someFn with the value if Some, or noneFn if None. Neither function returns a value, use this for side effects only.

If you need to return a value from each branch, use the free function `gofp.Match` instead.

name := o.Match(
    func(u User) { fmt.Println(u.Name) },
    func() string { fmt.Println("anonymous") },
)

func (Option[T]) OkOr

func (o Option[T]) OkOr(err error) Result[T]

OkOr converts Option[T] to Result[T]. Some(v) becomes Ok(v), None becomes Err(err).

r := gofp.Some(42).OkOr(errors.New("not found"))

func (Option[T]) OkOrElse

func (o Option[T]) OkOrElse(errFn func() error) Result[T]

OkOrElse converts Option[T] to a Result[T] tuple. Some(v) returns Ok(v), None calls errFn and returns Err(errFn()). Prefer over OkOr when the error is expensive to construct.

r := o.OkOrElse(func() error { return fmt.Errorf("user %d not found", id) })

func (Option[T]) Or

func (o Option[T]) Or(other Option[T]) Option[T]

Or returns the Option if it is Some, otherwise returns other.

gofp.Some(1).Or(gofp.Some(2))    // Some(1)
gofp.None[int]().Or(gofp.Some(2)) // Some(2)

func (Option[T]) OrElse

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

OrElse returns the Option if it is Some, otherwise calls f and returns its result. Prefer over Or when the fallback is expensive to compute.

o.OrElse(func() gofp.Option[User] { return getFromCache(id) })

func (Option[T]) ToPtr

func (o Option[T]) ToPtr() *T

ToPtr converts the Option to a *T pointer. Returns nil for None, a pointer to the contained value for Some.

Note: the returned pointer points to a copy of the value, not the original.

ptr := option.Some(42).ToPtr() 		// *int pointing to 42
ptr := option.None[int]().ToPtr()	// nil

func (Option[T]) Unwrap

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

Unwrap returns the contained value. Panics if the Option is None.

Use when you are certain the Option is Some, or in tests.

func (Option[T]) UnwrapOr

func (o Option[T]) UnwrapOr(defaultValue T) T

UnwrapOr returns the contained value if Some, or defaultValue if None.

name := o.UnwrapOr("anonymous")

func (Option[T]) UnwrapOrElse

func (o Option[T]) UnwrapOrElse(f func() T) T

UnwrapOrElse returns the contained value if Some, or calls f and returns its result if None. Prefer over UnwrapOr when the default is expensive to compute.

name := o.UnwrapOrElse(func() string { return generateDefaultName() })

func (Option[T]) UnwrapOrZero

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

UnwrapOrZero returns the contained value if Some, or the zero value of T if None.

count := o.UnwrapOrZero() // 0 if None

func (Option[T]) Xor

func (o Option[T]) Xor(other Option[T]) Option[T]

Xor returns Some if exactly one of o, other is Some. Returns None otherwise.

gofp.Some(1).Xor(gofp.None[int]())   	// Some(1)
gofp.None[int]().Xor(gofp.Some(2))   	// Some(2)
gofp.Some(1).Xor(gofp.Some(2))       	// None — both are Some
gofp.None[int]().Xor(gofp.None[int]())	// None — neither is Some

type Result

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

Result represents either a successful value of type T (Ok) or a failure with an error (Err).

Zero value is NOT valid, always use Ok(), Err(), or Of() constructors.

Result is immutable by design: all transformation methods return a new Result rather than modifying the receiver.

func Do

func Do(err error) Result[Unit]

Do wraps a single error return into Result[Unit]. Use for functions that return only error with no value.

gofp.Do(os.Remove("file.txt")).IfErr(func(err error) { log.Println(err) })

func Err

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

Err returns a failed Result containing err. If err is nil, Ok(zero value) is returned. This matches Go's convention where nil error means success.

r := result.Err[int](errors.New("not found"))

func Of

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

Of wraps a (T, error) tuple the standard Go return signature into a Result[T]. This is the primary bridge between stdlib and gostd.

result.Of(strconv.Atoi("42"))
result.Of(os.Open("file.txt"))
result.Of(json.Marshal(data))

func Of2

func Of2[A, B any](a A, b B, err error) Result[tuple.Pair[A, B]]

Of2 wraps a (A, B, error) tuple into Result[Pair[A, B]].

gofp.Of2(conn.Read(buf))

func Of3

func Of3[A, B, C any](a A, b B, c C, err error) Result[tuple.Triple[A, B, C]]

Of3 wraps a (A, B, C, error) tuple into Result[Triple[A, B, C]].

func Ok

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

Ok returns a successful Result containing value.

r := result.Ok(42)
r := result.Ok(user)

func Transpose

func Transpose[T any](o Option[Result[T]]) Result[Option[T]]

func Try

func Try[T any](f func() T) (r Result[T])

Try runs f and recovers from Result panics caused by Unwrap. If f panics with a gofp error, returns Err with that error. Real panics (nil pointer, index out of range) are re-panicked.

gofp.Try(func() string {
    age := parse(s).Unwrap()
    return format(age).Unwrap()
})

func (Result[T]) ContainsErr

func (r Result[T]) ContainsErr(target error) bool

ContainsErr returns true if the Result is Err and the error matches target using errors.Is semantics.

r.ContainsErr(ErrNotFound)

func (Result[T]) Err

func (r Result[T]) Err() Option[error]

Err converts Result[T] to Option[error]. Err(e) becomes Some(e), Ok becomes None.

r.Err().IfSome(func(err error) { log.Println(err) })

func (Result[T]) Expect

func (r Result[T]) Expect(msg string) T

Expect returns the contained value if Ok. Panics with the provided message (plus the error) if Err. Prefer over Unwrap when you want a meaningful panic message.

val := r.Expect("config must be loaded at startup")

func (Result[T]) ExpectErr

func (r Result[T]) ExpectErr(msg string) error

ExpectErr returns the contained error. Panics with msg if the Result is Ok.

err := r.ExpectErr("expected failure")

func (Result[T]) IfErr

func (r Result[T]) IfErr(f func(error)) Result[T]

IfErr calls f with the contained error if Err. Returns the original Result unchanged for chaining.

r.IfErr(func(err error) { log.Println(err) })

func (Result[T]) IfOk

func (r Result[T]) IfOk(f func(T)) Result[T]

IfOk calls f with the contained value if Ok. Returns the original Result unchanged for chaining.

r.IfOk(func(n int) { fmt.Println(n) })

func (Result[T]) IntoErr

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

IntoErr returns the raw error without any check. Returns nil if the Result is Ok. Use only when you are certain the Result is Err.

func (Result[T]) IntoOk

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

IntoOk returns the raw value without any check. Returns zero value if the Result is Err. Use only when you are certain the Result is Ok.

func (Result[T]) IsErr

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

IsErr reports whether the Result contains an error.

if r.IsErr() { ... }

func (Result[T]) IsErrAnd

func (r Result[T]) IsErrAnd(f func(error) bool) bool

IsErrAnd returns true if the Result is Err and f(err) returns true.

r.IsErrAnd(func(err error) bool { return errors.Is(err, ErrNotFound) })

func (Result[T]) IsOk

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

IsOk reports whether the Result contains a successful value.

if r.IsOk() { ... }

func (Result[T]) IsOkAnd

func (r Result[T]) IsOkAnd(f func(T) bool) bool

IsOkAnd returns true if the Result is Ok and f(value) returns true.

r.IsOkAnd(func(n int) bool { return n > 0 })

func (Result[T]) MapErr

func (r Result[T]) MapErr(f func(error) error) Result[T]

MapErr applies f to the error if Err, returning a new Result with the mapped error. Returns the Result unchanged if Ok.

r.MapErr(func(err error) error { return fmt.Errorf("wrapped: %w", err) })

func (Result[T]) Ok

func (r Result[T]) Ok() Option[T]

Ok converts Result[T] to Option[T]. Ok(v) becomes Some(v), Err becomes None.

gofp.Of(strconv.Atoi(s)).Ok() // Option[int]

func (Result[T]) Or

func (r Result[T]) Or(alternative Result[T]) Result[T]

Or returns the Result if Ok, otherwise returns alternative.

r.Or(gofp.Ok(0))

func (Result[T]) OrElse

func (r Result[T]) OrElse(f func(error) Result[T]) Result[T]

OrElse calls f with the error if Err, returning f's result. Returns the Result unchanged if Ok.

r.OrElse(func(err error) Result[int] { return gofp.Ok(0) })

func (Result[T]) Tap

func (r Result[T]) Tap(okFn func(T), errFn func(error)) Result[T]

Tap calls okFn if Ok or errFn if Err, then returns the Result unchanged. Either function may be nil.

r.Tap(
    func(v int) { log.Println("ok:", v) },
    func(err error) { log.Println("err:", err) },
)

func (Result[T]) Unpack

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

Unpack returns the (value, error) tuple. Use this to convert back to idiomatic Go returns.

value, err := r.Unpack()

func (Result[T]) Unwrap

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

Unwrap returns the contained value. Panics with the error message if the Result is an Err.

Use when you are certain the Result is Ok, or in tests.

val := r.Unwrap()

func (Result[T]) UnwrapErr

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

UnwrapErr returns the contained error. Panics if the Result is Ok.

func (Result[T]) UnwrapOr

func (r Result[T]) UnwrapOr(defaultValue T) T

UnwrapOr returns the contained value if Ok, or the provided default value if Err.

name := r.UnwrapOr("anonymous")

func (Result[T]) UnwrapOrElse

func (r Result[T]) UnwrapOrElse(f func(error) T) T

UnwrapOrElse returns the contained value if Ok, or calls f with the error and returns its result if Err. Prefer over UnwrapOr when the default is expensive to compute.

name := r.UnwrapOrElse(func(err error) string {
    log.Println(err)
    return "anonymous"
})

func (Result[T]) UnwrapOrZero

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

UnwrapOrZero returns the contained value if Ok, or the zero value of T if Err.

count := r.UnwrapOrZero() // 0 if Err

type ResultError

type ResultError string

ResultError is a string-based error type for sentinel errors within gofp. Defined as a named type to avoid allocation from errors.New.

const ErrNoResults ResultError = "result: no results provided"

ErrNoResults is returned by FirstOk when no results are provided.

func (ResultError) Error

func (e ResultError) Error() string

Error implements the error interface.

type Unit

type Unit struct{}

Unit represents the absence of a meaningful value. It is the Go equivalent of Rust's () type.

Directories

Path Synopsis
Package either provides the Either[L, R] type for Go.
Package either provides the Either[L, R] type for Go.
Package must provides panic-or-value helpers for Go.
Package must provides panic-or-value helpers for Go.
Package option provides free functions for transforming and combining Option[T] values from the gofp package.
Package option provides free functions for transforming and combining Option[T] values from the gofp package.
Package result provides free functions for transforming and combining Result[T] values from the gofp package.
Package result provides free functions for transforming and combining Result[T] values from the gofp package.
Package tuple provides generic Pair and Triple types for holding two or three values of potentially different types.
Package tuple provides generic Pair and Triple types for holding two or three values of potentially different types.

Jump to

Keyboard shortcuts

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