# Golang Samber Mo

> Implement, compose, or review typed optional, result, either, and computation values with `github.com/samber/mo`. Use when a project already exposes mo types or deliberately selects them for domain states, type-changing pipelines, serialization, or asynchronous abstractions.

- Skill: `reagin/golang-samber-mo` (Agent Skill)
- Install (CLI): `npx skillmds@latest add reagin/golang-samber-mo`
- Raw SKILL.md: https://api.skillmd.com/api/skills/reagin/golang-samber-mo/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: reagin (https://skillmd.com/u/reagin)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/reagin/golang-samber-mo

---


# samber/mo value and computation types

Read `go.mod`, imports, public signatures, conversions, serialization, database scans, and tests before changing a mo type. Confirm APIs in the pinned release; method and subpackage surfaces evolve independently.

## Choose the value model

| Type | Use when | Boundary question |
| --- | --- | --- |
| `Option[T]` | A value can be present or absent without failure | Is empty distinct from the zero value? |
| `Result[T]` | A computation has a success value or Go error | Must callers retain `errors.Is`/`errors.As`? |
| `Either[L, R]` | Both alternatives are meaningful domain values | Which side convention is already established? |
| `Either3` through `Either5` | A closed set needs more variants | Would a named domain type communicate the cases better? |
| `Future`, `IO`, `Task`, `State` families | Existing code relies on their evaluation model | Who starts, waits for, cancels, or owns the computation? |

Give nested types an explicit meaning. `Result[Option[T]]`, for example, can distinguish failure from a successful absence, but only when callers preserve both cases.

## Constructors and extraction

Representative constructors include `Some`, `None`, `TupleToOption`, `PointerToOption`, `Ok`, `Err`, `TupleToResult`, `Left`, and `Right`. Verify the exact generic arguments and conversion helpers before use.

Prefer checked extraction such as `Get`, `OrElse`, matching, or conversion back to ordinary Go returns. `MustGet` panics for the absent or error case. If code uses `mo.Do` to translate those panics into a `Result`, confirm which panic values it catches in the selected version and keep unrelated panics distinguishable.

## Same-type methods versus pipeline packages

Go methods cannot introduce new type parameters. In mo versions that follow this design:

- direct `Map` and `FlatMap` methods keep the same contained type;
- `github.com/samber/mo/option`, `/result`, and `/either` expose standalone functions for type-changing transforms;
- `PipeN` helpers compose several typed stages;
- `/either3`, `/either4`, and `/either5` provide the corresponding multi-variant transforms.

Use the direct method for a same-type step and a subpackage function when `T` changes to `U`. Check the pinned API for callback shapes: a direct method may accept a boolean, error, or wrapped return where the similarly named subpackage function does not.

## Preserve failure and boundary behavior

When wrapping `(T, error)`, retain the original error so inspection still works after extraction. Define whether absence maps to `nil`, a sentinel, an HTTP status, a database `NULL`, or another domain result.

Serialization and database support are type- and version-specific. Confirm implementations of `json.Marshaler`, `json.Unmarshaler`, `sql.Scanner`, or `driver.Valuer` rather than assuming every mo type supports every boundary. Test omitted, `null`, zero, malformed, and round-trip cases required by the external contract.

Future-like and lazy types need an explicit start and completion model. Verify whether work begins at construction, subscription, or `Run`; whether callbacks can run concurrently; and how cancellation reaches underlying I/O. A context stored beside a future is not cancellation unless the operation observes it.

## Keep pipelines reviewable

Use matching or an explicit branch where recovery, logging, cancellation, or partial results need distinct handling. Avoid repeated wrap/unwrap conversions across package boundaries; convert once at the boundary that owns the representation.

## Verification

Test every meaningful variant, the type-changing stages, zero values, extraction failure, error identity, and serialization or database behavior. For `Future`, `Task`, or related types, cover completion, rejection, timeout/cancellation, repeated observation, and goroutine cleanup without relying on narrow sleeps.

## References

- [package documentation](https://pkg.go.dev/github.com/samber/mo)
- [repository](https://github.com/samber/mo)

