omarluq/librecode/.librecode/skills/golang-samber-mo/SKILL.md
golang-samber-mo
Monadic types for Golang using samber/mo — Option, Result, Either, Future, IO, Task, and State types for type-safe nullable values, error handling, and functional composition with pipeline sub-packages. Apply when using or adopting samber/mo, when the codebase imports `github.com/samber/mo`, or when considering functional programming patterns as a safety design for Golang.
- Source repository stars
- 29
- Declared platforms
- 1
- Static risk flags
- 3
- Last source update
- 2026-08-25
- Source checked
- 2026-08-25
Decision brief
What it does: where it fits
Go 1.18+ library providing type-safe monadic types with zero dependencies. Inspired by Scala, Rust, and fp-ts.
Not for
- Tasks that require unconfirmed production actions or broad system permissions.
- Environments where the pinned source and install steps cannot be inspected.
Compatibility matrix
Platform support, with evidence labels
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Declared | Source record | Install path and trigger |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
Inspect first. Install second.
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/omarluq/librecode --skill ".librecode/skills/golang-samber-mo"Inspect the Agent Skill "golang-samber-mo" from https://github.com/omarluq/librecode/blob/55976d67b4363001b349a5adb9f9b87b27d0bfcd/.librecode/skills/golang-samber-mo/SKILL.md at commit 55976d67b4363001b349a5adb9f9b87b27d0bfcd. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
What the source asks the agent to do
- 01
Core Types at a Glance
Review the “Core Types at a Glance” section in the pinned source before continuing.
Review and apply the “Core Types at a Glance” source section. - 02
Option[T] — Nullable Values Without nil
Represents a value that is either present (Some) or absent (None). Eliminates nil pointer risks at the type level.
Represents a value that is either present (Some) or absent (None). Eliminates nil pointer risks at the type level.Key methods: Some, None, Get, MustGet, OrElse, OrEmpty, Map, FlatMap, Match, ForEach, ToPointer, IsPresent, IsAbsent.Option implements json.Marshaler/Unmarshaler, sql.Scanner, driver.Valuer — use it directly in JSON structs and database models. - 03
Result[T] — Error Handling as Values
Represents success (Ok) or failure (Err). Equivalent to Either[error, T] but specialized for Go's error pattern.
Represents success (Ok) or failure (Err). Equivalent to Either[error, T] but specialized for Go's error pattern.Go limitation: Direct methods (.Map, .FlatMap) cannot change the type parameter — Result[T].Map returns Result[T], not Result[U]. Go methods cannot introduce new type parameters. For type-changing transforms (e.g. Resul…Key methods: Ok, Err, Errf, TupleToResult, Try, Get, MustGet, OrElse, Map, FlatMap, MapErr, Match, ForEach, ToEither, IsOk, IsError. - 04
Either[L, R] — Discriminated Union of Two Types
Represents a value that is one of two possible types. Unlike Result, neither side implies success or failure — both are valid alternatives.
Represents a value that is one of two possible types. Unlike Result, neither side implies success or failure — both are valid alternatives.When to use Either vs Result: Use Result[T] when one path is an error. Use Either[L, R] when both paths are valid alternatives (cached vs fresh, left vs right, strategy A vs B).Either3[T1, T2, T3], Either4, and Either5 extend this to 3-5 type variants. - 05
Do Notation — Imperative Style with Monadic Safety
mo.Do wraps imperative code in a Result, catching panics from MustGet() calls:
mo.Do wraps imperative code in a Result, catching panics from MustGet() calls:Do notation bridges imperative Go style with monadic safety — write straight-line code, get automatic error propagation.
Permission review
Static risk signals and limitations
Runs scripts
The documentation asks the agent to run terminal commands or scripts.
go get github.com/samber/moReads files
The documentation asks the agent to read local files, directories, or repositories.
result := mo.TupleToResult(os.ReadFile("config.yaml"))Reads files
The documentation asks the agent to read local files, directories, or repositories.
mo.TupleToResult(os.ReadFile("config.yaml")),Network access
The documentation includes network, browsing, or remote request actions.
return mo.Right[CachedUser, FreshUser](db.Fetch(id))Evidence record
Why each signal appears
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 96/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 29 | Source | Repository attention, not individual Skill quality |
| Compatibility | 1 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Provenance and original SKILL.md
- Repository
- omarluq/librecode
- Skill path
- .librecode/skills/golang-samber-mo/SKILL.md
- Commit
- 55976d67b4363001b349a5adb9f9b87b27d0bfcd
- License
- MIT
- Collected
- 2026-08-25
- Default branch
- main
View the original SKILL.md
Persona: You are a Go engineer bringing functional programming safety to Go. You use monads to make impossible states unrepresentable — nil checks become type constraints, error handling becomes composable pipelines.
Thinking mode: Use ultrathink when designing multi-step Option/Result/Either pipelines. Wrong type choice creates unnecessary wrapping/unwrapping that defeats the purpose of monads.
samber/mo — Monads and Functional Abstractions for Go
Go 1.18+ library providing type-safe monadic types with zero dependencies. Inspired by Scala, Rust, and fp-ts.
Official Resources:
This skill is not exhaustive. Please refer to library documentation and code examples for more information. Context7 can help as a discoverability platform.
go get github.com/samber/mo
For an introduction to functional programming concepts and why monads are valuable in Go, see Monads Guide.
Core Types at a Glance
| Type | Purpose | Think of it as... |
|---|---|---|
Option[T] | Value that may be absent | Rust's Option, Java's Optional |
Result[T] | Operation that may fail | Rust's Result<T, E>, replaces (T, error) |
Either[L, R] | Value of one of two types | Scala's Either, TypeScript discriminated union |
EitherX[L, R] | Value of one of X types | Scala's Either, TypeScript discriminated union |
Future[T] | Async value not yet available | JavaScript Promise |
IO[T] | Lazy synchronous side effect | Haskell's IO |
Task[T] | Lazy async computation | fp-ts Task |
State[S, A] | Stateful computation | Haskell's State monad |
Option[T] — Nullable Values Without nil
Represents a value that is either present (Some) or absent (None). Eliminates nil pointer risks at the type level.
import "github.com/samber/mo"
name := mo.Some("Alice") // Option[string] with value
empty := mo.None[string]() // Option[string] without value
fromPtr := mo.PointerToOption(ptr) // nil pointer -> None
// Safe extraction
name.OrElse("Anonymous") // "Alice"
empty.OrElse("Anonymous") // "Anonymous"
// Transform if present, skip if absent
upper := name.Map(func(s string) (string, bool) {
return strings.ToUpper(s), true
})
Key methods: Some, None, Get, MustGet, OrElse, OrEmpty, Map, FlatMap, Match, ForEach, ToPointer, IsPresent, IsAbsent.
Option implements json.Marshaler/Unmarshaler, sql.Scanner, driver.Valuer — use it directly in JSON structs and database models.
For full API reference, see Option Reference.
Result[T] — Error Handling as Values
Represents success (Ok) or failure (Err). Equivalent to Either[error, T] but specialized for Go's error pattern.
// Wrap Go's (value, error) pattern
result := mo.TupleToResult(os.ReadFile("config.yaml"))
// Same-type transform — errors short-circuit automatically
upper := mo.Ok("hello").Map(func(s string) (string, error) {
return strings.ToUpper(s), nil
})
// Ok("HELLO")
// Extract with fallback
val := upper.OrElse("default")
Go limitation: Direct methods (.Map, .FlatMap) cannot change the type parameter — Result[T].Map returns Result[T], not Result[U]. Go methods cannot introduce new type parameters. For type-changing transforms (e.g. Result[[]byte] to Result[Config]), use sub-package functions or mo.Do:
import "github.com/samber/mo/result"
// Type-changing pipeline: []byte -> Config -> ValidConfig
parsed := result.Pipe2(
mo.TupleToResult(os.ReadFile("config.yaml")),
result.Map(func(data []byte) Config { return parseConfig(data) }),
result.FlatMap(func(cfg Config) mo.Result[ValidConfig] { return validate(cfg) }),
)
Key methods: Ok, Err, Errf, TupleToResult, Try, Get, MustGet, OrElse, Map, FlatMap, MapErr, Match, ForEach, ToEither, IsOk, IsError.
For full API reference, see Result Reference.
Either[L, R] — Discriminated Union of Two Types
Represents a value that is one of two possible types. Unlike Result, neither side implies success or failure — both are valid alternatives.
// API that returns either cached data or fresh data
func fetchUser(id string) mo.Either[CachedUser, FreshUser] {
if cached, ok := cache.Get(id); ok {
return mo.Left[CachedUser, FreshUser](cached)
}
return mo.Right[CachedUser, FreshUser](db.Fetch(id))
}
// Pattern match
result.Match(
func(cached CachedUser) mo.Either[CachedUser, FreshUser] { /* use cached */ },
func(fresh FreshUser) mo.Either[CachedUser, FreshUser] { /* use fresh */ },
)
When to use Either vs Result: Use Result[T] when one path is an error. Use Either[L, R] when both paths are valid alternatives (cached vs fresh, left vs right, strategy A vs B).
Either3[T1, T2, T3], Either4, and Either5 extend this to 3-5 type variants.
For full API reference, see Either Reference.
Do Notation — Imperative Style with Monadic Safety
mo.Do wraps imperative code in a Result, catching panics from MustGet() calls:
result := mo.Do(func() int {
// MustGet panics on None/Err — Do catches it as Result error
a := mo.Some(21).MustGet()
b := mo.Ok(2).MustGet()
return a * b // 42
})
// result is Ok(42)
result := mo.Do(func() int {
val := mo.None[int]().MustGet() // panics
return val
})
// result is Err("no such element")
Do notation bridges imperative Go style with monadic safety — write straight-line code, get automatic error propagation.
Pipeline Sub-Packages vs Direct Chaining
samber/mo provides two ways to compose operations:
Direct methods (.Map, .FlatMap) — work when the output type equals the input type:
opt := mo.Some(42)
doubled := opt.Map(func(v int) (int, bool) {
return v * 2, true
}) // Option[int]
Sub-package functions (option.Map, result.Map) — required when the output type differs from input:
import "github.com/samber/mo/option"
// int -> string type change: use sub-package Map
strOpt := option.Map(func(v int) string {
return fmt.Sprintf("value: %d", v)
})(mo.Some(42)) // Option[string]
Pipe functions (option.Pipe3, result.Pipe3) — chain multiple type-changing transformations readably:
import "github.com/samber/mo/option"
result := option.Pipe3(
mo.Some(42),
option.Map(func(v int) string { return strconv.Itoa(v) }),
option.Map(func(s string) []byte { return []byte(s) }),
option.FlatMap(func(b []byte) mo.Option[string] {
if len(b) > 0 { return mo.Some(string(b)) }
return mo.None[string]()
}),
)
Rule of thumb: Use direct methods for same-type transforms. Use sub-package functions + pipes when types change across steps.
For detailed pipeline API reference, see Pipelines Reference.
Common Patterns
JSON API responses with Option
type UserResponse struct {
Name string `json:"name"`
Nickname mo.Option[string] `json:"nickname"` // omits null gracefully
Bio mo.Option[string] `json:"bio"`
}
Database nullable columns
type User struct {
ID int
Email string
Phone mo.Option[string] // implements sql.Scanner + driver.Valuer
}
err := row.Scan(&u.ID, &u.Email, &u.Phone)
Wrapping existing Go APIs
// Convert map lookup to Option
func MapGet[K comparable, V any](m map[K]V, key K) mo.Option[V] {
return mo.TupleToOption(m[key]) // m[key] returns (V, bool)
}
Uniform extraction with Fold
mo.Fold works uniformly across Option, Result, and Either via the Foldable interface:
str := mo.Fold[error, int, string](
mo.Ok(42), // works with Option, Result, or Either
func(v int) string { return fmt.Sprintf("got %d", v) },
func(err error) string { return "failed" },
)
// "got 42"
Best Practices
- Prefer
OrElseoverMustGet—MustGetpanics on absent/error values; use it only insidemo.Doblocks where panics are caught, or when you are certain the value exists - Use
TupleToResultat API boundaries — convert Go's(T, error)toResult[T]at the boundary, then chain withMap/FlatMapinside your domain logic - Use
Result[T]for errors,Either[L, R]for alternatives — Result is specialized for success/failure; Either is for two valid types - Option for nullable fields, not zero values —
Option[string]distinguishes "absent" from "empty string"; use plainstringwhen empty string is a valid value - Chain, don't nest —
result.Map(...).FlatMap(...).OrElse(default)reads left-to-right; avoid nested if/else patterns when monadic chaining is cleaner - Use sub-package pipes for multi-step type transformations — when 3+ steps each change the type,
option.Pipe3(...)is more readable than nested function calls
For advanced types (Future, IO, Task, State), see Advanced Types Reference.
If you encounter a bug or unexpected behavior in samber/mo, open an issue at https://github.com/samber/mo/issues.
Cross-References
- -> See
samber/cc-skills-golang@golang-samber-loskill for functional collection transforms (Map, Filter, Reduce on slices) that compose with mo types - -> See
samber/cc-skills-golang@golang-error-handlingskill for idiomatic Go error handling patterns - -> See
samber/cc-skills-golang@golang-safetyskill for nil-safety and defensive Go coding - -> See
samber/cc-skills-golang@golang-databaseskill for database access patterns - -> See
samber/cc-skills-golang@golang-design-patternsskill for functional options and other Go patterns
Frequently asked questions
What to verify before installation and use
What does the golang-samber-mo source document cover?
Go 1.18+ library providing type-safe monadic types with zero dependencies. Inspired by Scala, Rust, and fp-ts.
How do I install golang-samber-mo?
The source record exposes this install command: npx skills add https://github.com/omarluq/librecode --skill ".librecode/skills/golang-samber-mo". Inspect the command and pinned source before running it.
Which Agent platforms does the source record declare?
The pinned source record declares support for: claude code.
Which permission-related actions were detected?
Static rules flagged exec-script, read-files, network in the source; the page lists the matching lines and excerpts.
Alternatives
Compare before choosing
samber/cc-skills-golang
golang-samber-mo
Monadic types for Golang using samber/mo — Option, Result, Either, Future, IO, Task, and State types for type-safe nullable values, error handling, and functional composition with pipeline sub-packages. Apply when using or adopting samber/mo, when the codebase imports `github.com/samber/mo`, or when considering functional programming patterns as a safety design for Golang.
oaustegard/claude-skills
featuring
Generate hierarchical _FEATURES.md files that describe what a codebase DOES from a user/consumer perspective, anchored to source symbols via tree-sitting. Supports large complex codebases through feature-driven decomposition into sub-feature files. Uses a multi-pass synthesis: orientation → detail → overview rewrite. Use when someone says "what does this do", "document features", "feature inventory", "_FEATURES.md", or needs to understand a codebase's purpose before modifying it. Complements tre
narrative-io/narrative-skills-marketplace
design-analysis
Translate a fuzzy analytical question into a rigorous investigation plan. Interrogates the ask, grounds the plan in the available data dictionary, applies analytical best practices, and produces a structured brief of query specifications for a downstream query-writing skill. Plans, does not write SQL. Use when: "why did X drop", "is there a relationship between A and B", "who are our highest-value customers", "what's driving the change in Y", "investigate this trend", "design an analysis for", "
vasilyu1983/AI-Agents-public
qa-testing-ios
Guides iOS testing with XCTest, XCUITest, Swift Testing, simctl, and xcresult. Use when choosing destinations, controlling flakes, or parsing test artifacts for native apps.