{"id":13412914,"url":"https://github.com/phelmkamp/valor","last_synced_at":"2026-01-12T02:53:31.867Z","repository":{"id":39794410,"uuid":"478812718","full_name":"phelmkamp/valor","owner":"phelmkamp","description":"Go option and result types that optionally contain a value","archived":false,"fork":false,"pushed_at":"2023-07-27T01:12:00.000Z","size":204,"stargazers_count":16,"open_issues_count":3,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-07-31T20:51:39.504Z","etag":null,"topics":["either","enum","error","golang","maybe","monad","option","result","singleton","tuple","unit"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phelmkamp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-04-07T03:26:46.000Z","updated_at":"2024-01-13T22:21:20.000Z","dependencies_parsed_at":"2024-01-08T15:02:46.426Z","dependency_job_id":null,"html_url":"https://github.com/phelmkamp/valor","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phelmkamp%2Fvalor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phelmkamp%2Fvalor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phelmkamp%2Fvalor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phelmkamp%2Fvalor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phelmkamp","download_url":"https://codeload.github.com/phelmkamp/valor/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221495314,"owners_count":16832458,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["either","enum","error","golang","maybe","monad","option","result","singleton","tuple","unit"],"created_at":"2024-07-30T20:01:31.015Z","updated_at":"2026-01-12T02:53:31.828Z","avatar_url":"https://github.com/phelmkamp.png","language":"Go","funding_links":[],"categories":["Functional","方法"],"sub_categories":["Search and Analytic Databases","检索及分析资料库","Advanced Console UIs"],"readme":"# valor\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/phelmkamp/valor.svg)](https://pkg.go.dev/github.com/phelmkamp/valor)\n[![Go Report Card](https://goreportcard.com/badge/github.com/phelmkamp/valor)](https://goreportcard.com/report/github.com/phelmkamp/valor)\n[![codecov](https://codecov.io/gh/phelmkamp/valor/branch/main/graph/badge.svg?token=GH8IYR78VD)](https://codecov.io/gh/phelmkamp/valor)\n\nThis module provides option and result types that optionally contain a value; hence the name valor, short for \"value or\".\n\nThis is not an attempt to make Go code look less like Go.\nInstead, the goal is to codify the [\"comma ok\"](https://blog.toshima.ru/2019/07/21/go-comma-ok-idiom.html) and\n[\"errors are values\"](https://go.dev/blog/errors-are-values) principles that Go already encourages.\n\n## Installation\n\n```bash\ngo get github.com/phelmkamp/valor\n```\n\n## Types\n\n### Value\n\n[`optional.Value`](https://pkg.go.dev/github.com/phelmkamp/valor/optional) is modeled after the \"comma ok\" idiom.\nIt contains a value (ok) or nothing (not ok).\n\n```go\nm := map[string]int{\"foo\": 42}\nval := optional.OfIndex(m, \"foo\")\nfmt.Println(val.IsOk()) // true\n\nvar foo int\nfmt.Println(val.Ok(\u0026foo), foo) // true 42\n\nvalStr := optional.Map(val, strconv.Itoa)\nfmt.Println(valStr) // {42 true}\n\nval = optional.OfIndex(m, \"bar\")\nfmt.Println(val.Or(-1))                          // -1\nfmt.Println(val.OrZero())                        // 0\nfmt.Println(val.OrElse(func() int { return 1 })) // 1\n```\n\n### Result\n\n[`result.Result`](https://pkg.go.dev/github.com/phelmkamp/valor/result) contains either a value or an error.\n\n```go\n// traditional\nif res := result.Of(w.Write([]byte(\"foo\"))); res.IsError() {\n    fmt.Println(res.Error())\n    return\n}\n\n// try to get value, printing wrapped error if not ok\n// note: only relevant values are in-scope after handling\nvar n int\nif res := result.Of(w.Write([]byte(\"foo\"))); !res.Value().Ok(\u0026n) {\n    fmt.Println(res.Errorf(\"Write() failed: %w\").Error())\n    return\n}\n\n// same as above with multiple values\nvar s string\nvar b bool\nif res := two.TupleResultOf(multi(false)); !res.Value().Do(\n    func(t two.Tuple[string, bool]) { s, b = t.Values() },\n).IsOk() {\n    fmt.Println(res.Errorf(\"multi() failed: %w\").Error())\n    return\n}\n\n// errors.Is\nif res := result.Of(w.Write([]byte(\"foo\"))); res.ErrorIs(io.ErrShortWrite) {\n    fmt.Println(res.Error())\n    return\n}\n\n// errors.As\nif res := result.Of(w.Write([]byte(\"foo\"))); res.IsError() {\n    var err *fs.PathError\n    if res.ErrorAs(\u0026err) {\n        fmt.Println(\"path=\" + err.Path)\n    }\n    fmt.Println(res.Error())\n    return\n}\n\n// errors.Unwrap\nif res := result.Of(mid(true)); res.IsError() {\n    fmt.Println(res.ErrorUnwrap().Error())\n    return\n}\n```\n\n### Tuples\n\n[`unit.Type`](https://pkg.go.dev/github.com/phelmkamp/valor/tuple/unit), [`singleton.Set`](https://pkg.go.dev/github.com/phelmkamp/valor/tuple/singleton),\n[`two.Tuple`](https://pkg.go.dev/github.com/phelmkamp/valor/tuple/two), [`three.Tuple`](https://pkg.go.dev/github.com/phelmkamp/valor/tuple/three), and\n[`four.Tuple`](https://pkg.go.dev/github.com/phelmkamp/valor/tuple/four) contain zero through four values respectively.\nAmong other things, they enable `Value` and `Result` to contain a variable number of values.\n\n{% raw %}\n```go\nget := func(string, int, bool) {\n    return \"a\", 1, true\n}\nval := two.TupleValueOf(get())\nfmt.Println(val) // {{a 1} true}\n```\n{% endraw %}\n\n### Enum\n\n[`enum.Enum`](https://pkg.go.dev/github.com/phelmkamp/valor/enum) is an enumerated type.\nIt's initialized with a set of allowed values and then each \"copy\" optionally contains a currently selected value.\n\n```go\nconst (\n\tClubs    = \"clubs\"\n\tDiamonds = \"diamonds\"\n\tHearts   = \"hearts\"\n\tSpades   = \"spades\"\n)\nvar Suit = enum.OfString(Clubs, Diamonds, Hearts, Spades)\nfunc main() {\n    fmt.Println(Suit.Values())          // [clubs diamonds hearts spades]\n    fmt.Println(Suit.ValueOf(\"Foo\"))    // { false}\n    fmt.Println(Suit.ValueOf(Hearts))   // {hearts true}\n}\n```\n\n## Similar concepts in other languages\n\n### Rust\n\n`Value` is like Rust's [`Option`](https://doc.rust-lang.org/std/option/enum.Option.html).\n`Result` is like Rust's [`Result`](https://doc.rust-lang.org/std/result/enum.Result.html).\n\nA `switch` statement provides similar semantics to Rust's `match`:\n\n```go\nvar foo int\nswitch val {\ncase val.OfOk():\n    foo = val.MustOk()\n    fmt.Println(\"Ok\", foo)\ncase optional.OfNotOk[int]():\n    fmt.Println(\"Not Ok\")\n    return\n}\n\nvar n int\nswitch res {\ncase res.OfOk():\n    n = res.Value().MustOk()\n    fmt.Println(\"Ok\", n)\ncase res.OfError():\n    fmt.Println(\"Error\", res.Error())\n    return\n}\n```\n\n### Java\n\n`Value` is like Java's [`Optional`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Optional.html).\n\n### More\n\n * [https://en.wikipedia.org/wiki/Result_type](https://en.wikipedia.org/wiki/Result_type)\n * [https://en.wikipedia.org/wiki/Option_type](https://en.wikipedia.org/wiki/Option_type)\n\n## Releases\n\nThis module is currently at v0 but every effort will be made to avoid breaking changes.\nInstead, functionality will be deprecated as needed with plans to remove in v1.\n\n## Linter\n\n[valorcheck](https://github.com/phelmkamp/valor/tree/main/valorcheck#readme) is a linter to check that access to an optional value is guarded against the case where the value is not present.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphelmkamp%2Fvalor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphelmkamp%2Fvalor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphelmkamp%2Fvalor/lists"}