Documentation
¶
Overview ¶
package option implements the Option monad, a data type that can have a defined value or none
Package optional provides an optic for focusing on values that may not exist.
Overview ¶
Optional is an optic used to zoom inside a product. Unlike the Lens, the element that the Optional focuses on may not exist. An Optional[S, A] represents a relationship between a source type S and a focus type A, where the focus may or may not be present.
Optional Laws ¶
An Optional must satisfy the following laws, which are consistent with other functional programming libraries such as monocle-ts (https://gcanti.github.io/monocle-ts/modules/Optional.ts.html) and the Haskell lens library (https://hackage.haskell.org/package/lens):
GetSet Law (No-op on None): If GetOption(s) returns None, then Set(a)(s) must return s unchanged (no-op). This ensures that attempting to update a value that doesn't exist has no effect.
Formally: GetOption(s) = None => Set(a)(s) = s
SetGet Law (Get what you Set): If GetOption(s) returns Some(_), then GetOption(Set(a)(s)) must return Some(a). This ensures that after setting a value, you can retrieve it.
Formally: GetOption(s) = Some(_) => GetOption(Set(a)(s)) = Some(a)
SetSet Law (Last Set Wins): Setting twice is the same as setting once with the final value.
Formally: Set(b)(Set(a)(s)) = Set(b)(s)
No-op Behavior ¶
A key property of Optional is that updating a value for which GetOption returns None is a no-op. This behavior is implemented through the optionalModify function, which only applies the modification if the optional value exists. When GetOption returns None, the original structure is returned unchanged.
This is consistent with the behavior in:
- monocle-ts: Optional.modify returns the original value when the optional doesn't match
- Haskell lens: over and set operations are no-ops when the traversal finds no targets
Example ¶
type Person struct {
Name string
Age int
}
// Create an optional that focuses on non-empty names
nameOptional := MakeOptional(
func(p Person) option.Option[string] {
if p.Name != "" {
return option.Some(p.Name)
}
return option.None[string]()
},
func(p Person, name string) Person {
p.Name = name
return p
},
)
// When the optional matches, Set updates the value
person1 := Person{Name: "Alice", Age: 30}
updated1 := nameOptional.Set("Bob")(person1)
// updated1.Name == "Bob"
// When the optional doesn't match (Name is empty), Set is a no-op
person2 := Person{Name: "", Age: 30}
updated2 := nameOptional.Set("Bob")(person2)
// updated2 == person2 (unchanged)
Index ¶
- func IsoComposeIso[S, A, B any](ab Iso[A, B]) func(Iso[S, A]) Iso[S, B]
- func IsoComposeLens[S, A, B any](ab Lens[A, B]) func(Iso[S, A]) Lens[S, B]
- func IsoFrom[S, A any](a A) func(Iso[S, A]) S
- func IsoIMap[S, A, B any](ab func(A) B, ba func(B) A) func(Iso[S, A]) Iso[S, B]
- func IsoModify[S any, FCT ~func(A) A, A any](f FCT) func(Iso[S, A]) Endomorphism[S]
- func IsoTo[A, S any](s S) func(Iso[S, A]) A
- func IsoUnwrap[A, S any](s S) func(Iso[S, A]) A
- func IsoWrap[S, A any](a A) func(Iso[S, A]) S
- func LensModify[S any, FCT ~func(A) A, A any](f FCT) func(Lens[S, A]) Endomorphism[S]
- func LensModifyF[S, A, HKTA, HKTS any](fmap functor.MapType[A, S, HKTA, HKTS]) func(func(A) HKTA) func(Lens[S, A]) func(S) HKTS
- func LensSet[S any, A any](a A) func(Lens[S, A]) Endomorphism[S]
- func OptionCompactArray[A any](fa []Option[A]) []A
- func OptionCompactArrayG[A1 ~[]Option[A], A2 ~[]A, A any](fa A1) A2
- func OptionFold[A, B any](onNone func() B, onSome func(a A) B) func(Option[A]) B
- func OptionFromEq[A any](pred eq.Eq[A]) func(A) OptionKleisli[A, A]
- func OptionFromStrictEq[A comparable]() func(A) OptionKleisli[A, A]
- func OptionGetOrElse[A any](onNone func() A) func(Option[A]) A
- func OptionIsNone[T any](val Option[T]) bool
- func OptionIsSome[T any](val Option[T]) bool
- func OptionMonadFold[A, B any](ma Option[A], onNone func() B, onSome func(A) B) B
- func OptionMonadGetOrElse[A any](fa Option[A], onNone func() A) A
- func OptionReduce[A, B any](f func(B, A) B, initial B) func(Option[A]) B
- func OptionSequence2[T1, T2, R any](f func(T1, T2) Option[R]) func(Option[T1], Option[T2]) Option[R]
- func OptionToNillable2[A any](fa Option[A]) *A
- func OptionUnwrap[A any](ma Option[A]) (A, bool)
- func OptionalAsTraversal[R ~func(func(A) HKTA) func(S) HKTS, S, A, HKTS, HKTA any](fof pointed.OfType[S, HKTS], fmap functor.MapType[A, S, HKTA, HKTS]) func(Optional[S, A]) R
- func OptionalFromPredicate[S, A any](pred func(A) bool) func(func(S) A, func(S, A) S) Optional[S, A]
- func OptionalFromPredicateRef[S, A any](pred func(A) bool) func(func(*S) A, func(*S, A) *S) Optional[*S, A]
- func OptionalModifyOption[S, A any](f func(A) A) func(Optional[S, A]) OptionKleisli[S, S]
- func OptionalSetOption[S, A any](a A) func(Optional[S, A]) OptionKleisli[S, S]
- func PrismAsTraversal[R ~func(func(A) HKTA) func(S) HKTS, S, A, HKTS, HKTA any](fof pointed.OfType[S, HKTS], fmap functor.MapType[A, S, HKTA, HKTS]) func(Prism[S, A]) R
- func PrismSet[S, A any](a A) func(Prism[S, A]) Endomorphism[S]
- type Endomorphism
- type Iso
- type Lens
- func IsoAsLens[S, A any](sa Iso[S, A]) Lens[S, A]
- func IsoAsLensRef[S, A any](sa Iso[*S, A]) Lens[*S, A]deprecated
- func LensId[S any]() Lens[S, S]
- func LensIdRef[S any]() Lens[*S, *S]
- func MakeLens[GET ~func(S) A, SET ~func(S, A) S, S, A any](get GET, set SET) Lens[S, A]
- func MakeLensCurried[GET ~func(S) A, SET ~func(A) Endomorphism[S], S, A any](get GET, set SET) Lens[S, A]
- func MakeLensCurriedRefWithName[GET ~func(*S) A, SET ~func(A) Endomorphism[*S], S, A any](get GET, set SET, name string) Lens[*S, A]
- func MakeLensCurriedWithName[GET ~func(S) A, SET ~func(A) Endomorphism[S], S, A any](get GET, set SET, name string) Lens[S, A]
- func MakeLensRef[GET ~func(*S) A, SET func(*S, A) *S, S, A any](get GET, set SET) Lens[*S, A]
- func MakeLensRefCurried[S, A any](get func(*S) A, set func(A) Endomorphism[*S]) Lens[*S, A]
- func MakeLensRefCurriedWithName[S, A any](get func(*S) A, set func(A) Endomorphism[*S], name string) Lens[*S, A]
- func MakeLensRefWithName[GET ~func(*S) A, SET func(*S, A) *S, S, A any](get GET, set SET, name string) Lens[*S, A]
- func MakeLensStrict[GET ~func(*S) A, SET func(*S, A) *S, S any, A comparable](get GET, set SET) Lens[*S, A]
- func MakeLensStrictWithName[GET ~func(*S) A, SET func(*S, A) *S, S any, A comparable](get GET, set SET, name string) Lens[*S, A]
- func MakeLensWithEq[GET ~func(*S) A, SET func(*S, A) *S, S, A any](pred EQ.Eq[A], get GET, set SET) Lens[*S, A]
- func MakeLensWithEqWithName[GET ~func(*S) A, SET func(*S, A) *S, S, A any](pred EQ.Eq[A], get GET, set SET, name string) Lens[*S, A]
- func MakeLensWithName[GET ~func(S) A, SET ~func(S, A) S, S, A any](get GET, set SET, name string) Lens[S, A]
- type LensKleisli
- type LensOperator
- func LensComposeIso[S, A, B any](ab Iso[A, B]) LensOperator[S, A, B]
- func LensComposeLens[S, A, B any](ab Lens[A, B]) LensOperator[S, A, B]
- func LensComposeLensRef[S, A, B any](ab Lens[A, B]) LensOperator[*S, A, B]deprecated
- func LensIMap[S any, AB ~func(A) B, BA ~func(B) A, A, B any](ab AB, ba BA) LensOperator[S, A, B]
- type Option
- func OptionFlatten[A any](mma Option[Option[A]]) Option[A]
- func OptionFromNillable[A any](a *A) Option[*A]deprecated
- func OptionFromNillable2[A any](a *A) Option[A]
- func OptionInstanceOf[T any](src any) Option[T]
- func OptionMonadAlt[A any](fa Option[A], that func() Option[A]) Option[A]
- func OptionMonadAp[B, A any](fab Option[func(A) B], fa Option[A]) Option[B]
- func OptionMonadChain[A, B any](fa Option[A], f OptionKleisli[A, B]) Option[B]
- func OptionMonadChainFirst[A, B any](ma Option[A], f OptionKleisli[A, B]) Option[A]
- func OptionMonadChainTo[A, B any](ma Option[A], mb Option[B]) Option[B]
- func OptionMonadFlap[B, A any](fab Option[func(A) B], a A) Option[B]
- func OptionMonadMap[A, B any](fa Option[A], f func(A) B) Option[B]
- func OptionMonadMapTo[A, B any](fa Option[A], b B) Option[B]
- func OptionMonadSequence2[T1, T2, R any](o1 Option[T1], o2 Option[T2], f func(T1, T2) Option[R]) Option[R]
- func OptionNone[T any]() Option[T]
- func OptionOf[T any](value T) Option[T]
- func OptionSequenceArray[A any](ma []Option[A]) Option[[]A]
- func OptionSequenceArrayG[GA ~[]A, GOA ~[]Option[A], A any](ma GOA) Option[GA]
- func OptionSome[T any](value T) Option[T]
- func OptionToAny[T any](src T) Option[any]
- func OptionTryCatch[A any](f func() (A, error)) Option[A]
- func OptionZero[A any]() Option[A]
- type OptionKleisli
- func OptionFromNonZero[A comparable]() OptionKleisli[A, A]
- func OptionFromPredicate[A any](pred Predicate[A]) OptionKleisli[A, A]
- func OptionFromValidation[A, B any](f func(A) (B, bool)) OptionKleisli[A, B]
- func OptionFromZero[A comparable]() OptionKleisli[A, A]
- func OptionOptionize1[F ~func(T0) (R, bool), T0, R any](f F) OptionKleisli[T0, R]
- func OptionTraverseArray[A, B any](f OptionKleisli[A, B]) OptionKleisli[[]A, []B]
- func OptionTraverseArrayG[GA ~[]A, GB ~[]B, A, B any](f OptionKleisli[A, B]) OptionKleisli[GA, GB]
- func OptionTraverseArrayWithIndex[A, B any](f func(int, A) Option[B]) OptionKleisli[[]A, []B]
- func OptionTraverseArrayWithIndexG[GA ~[]A, GB ~[]B, A, B any](f func(int, A) Option[B]) OptionKleisli[GA, GB]
- type OptionKleisliI
- type OptionOperator
- func OptionAlt[A any](that func() Option[A]) OptionOperator[A, A]
- func OptionAp[B, A any](fa Option[A]) OptionOperator[func(A) B, B]
- func OptionChain[A, B any](f OptionKleisli[A, B]) OptionOperator[A, B]
- func OptionChainFirst[A, B any](f OptionKleisli[A, B]) OptionOperator[A, A]
- func OptionChainOptionNone[A any](onNone func() Option[A]) OptionOperator[A, A]
- func OptionChainTo[A, B any](mb Option[B]) OptionOperator[A, B]
- func OptionFilter[A any](pred Predicate[A]) OptionOperator[A, A]
- func OptionFlap[B, A any](a A) OptionOperator[func(A) B, B]
- func OptionMap[A, B any](f func(a A) B) OptionOperator[A, B]
- func OptionMapTo[A, B any](b B) OptionOperator[A, B]
- type OptionTraversable
- type Optional
- func MakeOptional[S, A any](get OptionKleisli[S, A], set func(S, A) S) Optional[S, A]
- func MakeOptionalCurried[S, A any](get OptionKleisli[S, A], set func(A) func(S) S) Optional[S, A]
- func MakeOptionalCurriedWithName[S, A any](get OptionKleisli[S, A], set func(A) func(S) S, name string) Optional[S, A]
- func MakeOptionalRef[S, A any](get OptionKleisli[*S, A], set func(*S, A) *S) Optional[*S, A]
- func MakeOptionalRefCurriedWithName[S, A any](get OptionKleisli[*S, A], set func(A) func(*S) *S, name string) Optional[*S, A]
- func MakeOptionalRefWithName[S, A any](get OptionKleisli[*S, A], set func(*S, A) *S, name string) Optional[*S, A]
- func MakeOptionalWithName[S, A any](get OptionKleisli[S, A], set func(S, A) S, name string) Optional[S, A]
- func OptionalId[S any]() Optional[S, S]
- func OptionalIdRef[S any]() Optional[*S, *S]
- type OptionalKleisli
- type OptionalOperator
- func OptionalComposeOptional[S, A, B any](ab Optional[A, B]) OptionalOperator[S, A, B]
- func OptionalComposeOptionalRef[S, A, B any](ab Optional[A, B]) OptionalOperator[*S, A, B]
- func OptionalIChain[S, A, B any](ab OptionKleisli[A, B], ba OptionKleisli[B, A]) OptionalOperator[S, A, B]
- func OptionalIChainAny[S, A any]() OptionalOperator[S, any, A]
- func OptionalIMap[S, A, B any](ab func(A) B, ba func(B) A) OptionalOperator[S, A, B]
- type Predicate
- type Prism
- func MakePrism[S, A any](get OptionKleisli[S, A], rev func(A) S) Prism[S, A]
- func MakePrismWithName[S, A any](get OptionKleisli[S, A], rev func(A) S, name string) Prism[S, A]
- func PrismFromOption[T any]() Prism[Option[T], T]
- func PrismFromPredicate[S any](pred func(S) bool) Prism[S, S]
- func PrismId[S any]() Prism[S, S]
- func PrismSome[S, A any](soa Prism[S, Option[A]]) Prism[S, A]
- type PrismKleisli
- type PrismOperator
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IsoComposeIso ¶
IsoComposeIso combines two isomorphisms to create a new isomorphism. Given Iso[S, A] and Iso[A, B], creates Iso[S, B]. The resulting isomorphism first applies the outer iso (S → A), then the inner iso (A → B).
Type Parameters:
- S: The outermost source type
- A: The intermediate type
- B: The innermost target type
Parameters:
- ab: The inner isomorphism (A → B)
Returns:
- A function that takes the outer isomorphism (S → A) and returns the composed isomorphism (S → B)
Example:
metersToKm := MakeIso(
func(m float64) float64 { return m / 1000 },
func(km float64) float64 { return km * 1000 },
)
kmToMiles := MakeIso(
func(km float64) float64 { return km * 0.621371 },
func(mi float64) float64 { return mi / 0.621371 },
)
// IsoComposeIso: meters → kilometers → miles
metersToMiles := F.Pipe1(metersToKm, IsoComposeIso[float64](kmToMiles))
miles := metersToMiles.Get(5000) // ~3.11 miles
meters := metersToMiles.ReverseGet(3.11) // ~5000 meters
func IsoComposeLens ¶
IsoComposeLens combines an isomorphism with a lens to produce a new lens.
Given an isomorphism Iso[S, A] and a lens Lens[A, B], IsoComposeLens creates a Lens[S, B]. Internally the isomorphism is first converted to a Lens[S, A] via IsoAsLens, then composed with the provided lens using LensComposeLens.
This is useful when the outer view of a structure is captured by a total, invertible transformation (an iso) and you want to drill further into the result with a lens — for example, when S is a newtype wrapper around A and you need to focus on a field of A.
The resulting lens satisfies all three lens laws whenever both the isomorphism and the inner lens individually satisfy them.
The composition follows: (sa ∘ ab).Get(s) = ab.Get(sa.Get(s))
Type Parameters:
- S: Outermost source type — the input to the resulting lens
- A: Intermediate type — the target of the iso and the source of the inner lens
- B: Inner focus type — the focus of the resulting lens
Parameters:
- ab: Lens from A to B (inner lens)
Returns:
- A function that takes an Iso[S, A] and returns a Lens[S, B]
Example:
type Celsius float64
type Thermometer struct{ Reading Celsius }
// Isomorphism: float64 ↔ Celsius
floatToCelsius := MakeIso(
func(f float64) Celsius { return Celsius(f) },
func(c Celsius) float64 { return float64(c) },
)
// Lens: Thermometer → Celsius (focuses on the Reading field)
readingLens := MakeLens(
func(t Thermometer) Celsius { return t.Reading },
func(t Thermometer, c Celsius) Thermometer { t.Reading = c; return t },
)
// Compose: float64 → Celsius → Thermometer.Reading (Celsius)
// Result type: Lens[float64, Celsius]
tempLens := F.Pipe1(floatToCelsius, IsoComposeLens[float64](readingLens))
t := Thermometer{Reading: 100}
reading := tempLens.Get(100.0) // Celsius(100)
updated := tempLens.Set(Celsius(0))(0.0) // Thermometer{Reading: 0}
See Also:
- IsoComposeIso: the variant that composes with an Iso[A, B] instead of a Lens[A, B]
- LensComposeLens: the pure-lens equivalent
- IsoAsLens: converts an Iso to a Lens directly
func IsoFrom ¶
IsoFrom wraps a target value into a source value using an isomorphism. This is an alias for Wrap, provided for semantic clarity when the direction of conversion is important.
Type Parameters:
- S: The source type to convert from
- A: The target type
Parameters:
- a: The target value to convert
Returns:
- A function that takes an Iso[S, A] and returns the converted value of type S
Example:
type Email string
type ValidatedEmail struct{ value Email }
emailIso := MakeIso(
func(ve ValidatedEmail) Email { return ve.value },
func(e Email) ValidatedEmail { return ValidatedEmail{value: e} },
)
// Convert from Email
validated := IsoFrom[ValidatedEmail](Email("admin@example.com"))(emailIso)
// ValidatedEmail{value: "admin@example.com"}
func IsoIMap ¶
IsoIMap bidirectionally maps the target type of an isomorphism. Given Iso[S, A] and functions A → B and B → A, creates Iso[S, B]. This allows you to transform both directions of an isomorphism.
Type Parameters:
- S: The source type (unchanged)
- A: The original target type
- B: The new target type
Parameters:
- ab: Function to map from A to B
- ba: Function to map from B to A (inverse of ab)
Returns:
- A function that transforms Iso[S, A] to Iso[S, B]
Example:
type Celsius float64
type Kelvin float64
celsiusIso := Id[Celsius]()
// Create isomorphism to Kelvin
celsiusToKelvin := F.Pipe1(
celsiusIso,
IsoIMap(
func(c Celsius) Kelvin { return Kelvin(c + 273.15) },
func(k Kelvin) Celsius { return Celsius(k - 273.15) },
),
)
kelvin := celsiusToKelvin.Get(Celsius(20)) // 293.15 K
celsius := celsiusToKelvin.ReverseGet(Kelvin(293.15)) // 20°C
Note: The functions ab and ba must be inverses of each other to maintain the isomorphism laws.
func IsoModify ¶
func IsoModify[S any, FCT ~func(A) A, A any](f FCT) func(Iso[S, A]) Endomorphism[S]
IsoModify creates a function that applies a transformation in the target space. It converts the source value to the target type, applies the transformation, then converts back to the source type.
Type Parameters:
- S: The source type
- FCT: The transformation function type (A → A)
- A: The target type
Parameters:
- f: The transformation function to apply in the target space
Returns:
- A function that takes an Iso[S, A] and returns an endomorphism (S → S)
Example:
type Meters float64
type Kilometers float64
mToKm := MakeIso(
func(m Meters) Kilometers { return Kilometers(m / 1000) },
func(km Kilometers) Meters { return Meters(km * 1000) },
)
// Double the distance in kilometers, result in meters
doubled := IsoModify[Meters](func(km Kilometers) Kilometers {
return km * 2
})(mToKm)(Meters(5000))
// Result: Meters(10000)
func IsoTo ¶
IsoTo extracts the target value from a source value using an isomorphism. This is an alias for Unwrap, provided for semantic clarity when the direction of conversion is important.
Type Parameters:
- A: The target type to convert to
- S: The source type
Parameters:
- s: The source value to convert
Returns:
- A function that takes an Iso[S, A] and returns the converted value of type A
Example:
type Email string
type ValidatedEmail struct{ value Email }
emailIso := MakeIso(
func(ve ValidatedEmail) Email { return ve.value },
func(e Email) ValidatedEmail { return ValidatedEmail{value: e} },
)
// Convert to Email
email := IsoTo[Email](ValidatedEmail{value: "user@example.com"})(emailIso)
// "user@example.com"
func IsoUnwrap ¶
IsoUnwrap extracts the target value from a source value using an isomorphism. This is a convenience function that applies the Get function of the isomorphism.
Type Parameters:
- A: The target type to extract
- S: The source type
Parameters:
- s: The source value to unwrap
Returns:
- A function that takes an Iso[S, A] and returns the unwrapped value of type A
Example:
type UserId int
userIdIso := MakeIso(
func(id UserId) int { return int(id) },
func(i int) UserId { return UserId(i) },
)
rawId := IsoUnwrap[int](UserId(42))(userIdIso) // 42
Note: This function is also available as To for semantic clarity.
func IsoWrap ¶
IsoWrap wraps a target value into a source value using an isomorphism. This is a convenience function that applies the ReverseGet function of the isomorphism.
Type Parameters:
- S: The source type to wrap into
- A: The target type
Parameters:
- a: The target value to wrap
Returns:
- A function that takes an Iso[S, A] and returns the wrapped value of type S
Example:
type UserId int
userIdIso := MakeIso(
func(id UserId) int { return int(id) },
func(i int) UserId { return UserId(i) },
)
userId := IsoWrap[UserId](42)(userIdIso) // UserId(42)
Note: This function is also available as From for semantic clarity.
func LensModify ¶
func LensModify[S any, FCT ~func(A) A, A any](f FCT) func(Lens[S, A]) Endomorphism[S]
LensModify transforms a value through a lens using a transformation F.
Instead of setting a specific value, LensModify applies a function to the current value. This is useful for updates like incrementing a counter, appending to a string, etc. If the transformation doesn't change the value, the original structure is returned.
Type Parameters:
- S: Structure type
- FCT: Transformation function type (A → A)
- A: Focus type
Parameters:
- f: Transformation function to apply to the focused value
Returns:
- A function that takes a Lens[S, A] and returns an Endomorphism[S]
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 },
)
counter := Counter{Value: 5}
// Increment the counter
incremented := F.Pipe2(
valueLens,
lens.LensModify[Counter](func(v int) int { return v + 1 }),
F.Ap(counter),
)
// incremented.Value == 6
// Double the counter
doubled := F.Pipe2(
valueLens,
lens.LensModify[Counter](func(v int) int { return v * 2 }),
F.Ap(counter),
)
// doubled.Value == 10
func LensModifyF ¶
func LensModifyF[S, A, HKTA, HKTS any]( fmap functor.MapType[A, S, HKTA, HKTS], ) func(func(A) HKTA) func(Lens[S, A]) func(S) HKTS
LensModifyF transforms a value through a lens using a function that returns a value in a functor context.
This is the functorial version of Modify, allowing transformations that produce effects (like Option, Either, IO, etc.) while updating the focused value. The functor's map operation is used to apply the lens's setter to the transformed value, preserving the computational context.
This function corresponds to modifyF from monocle-ts, enabling effectful updates through lenses.
Type Parameters ¶
- S: Structure type
- A: Focus type (the value being transformed)
- HKTA: Higher-kinded type containing the transformed value (e.g., Option[A], Either[E, A])
- HKTS: Higher-kinded type containing the updated structure (e.g., Option[S], Either[E, S])
Parameters ¶
- fmap: A functor map operation that transforms A to S within the functor context
Returns ¶
- A curried function that takes: 1. A transformation function (A → HKTA) 2. A Lens[S, A] 3. A structure S And returns the updated structure in the functor context (HKTS)
Example Usage ¶
type Person struct {
Name string
Age int
}
ageLens := lens.MakeLens(
func(p Person) int { return p.Age },
func(p Person, age int) Person { p.Age = age; return p },
)
// Validate age is positive, returning Option
validateAge := func(age int) option.Option[int] {
if age > 0 {
return option.Some(age)
}
return option.None[int]()
}
// Create a modifier that validates while updating
modifyAge := lens.LensModifyF[Person, int](option.Functor[int, Person]().Map)
person := Person{Name: "Alice", Age: 30}
result := modifyAge(validateAge)(ageLens)(person)
// result is Some(Person{Name: "Alice", Age: 30})
invalidResult := modifyAge(func(age int) option.Option[int] {
return option.None[int]()
})(ageLens)(person)
// invalidResult is None[Person]()
See Also ¶
- Modify: Non-functorial version for simple transformations
- functor.Functor: The functor interface used for mapping
func LensSet ¶
func LensSet[S any, A any](a A) func(Lens[S, A]) Endomorphism[S]
LensSet returns a function that updates the focus of a lens to a constant value.
This is a convenience helper for partially applying a value before supplying the lens, making it useful in composition pipelines with F.Pipe.
Example:
type Counter struct {
Value int
}
valueLens := lens.MakeLens(
func(c Counter) int { return c.Value },
func(c Counter, value int) Counter {
c.Value = value
return c
},
)
counter := Counter{Value: 5}
updated := F.Pipe2(
10,
lens.LensSet[Counter](10),
F.Ap(valueLens),
)
// updated.Value == 10
func OptionCompactArray ¶ added in v2.3.120
OptionCompactArray filters an array of Options, keeping only the Some values and discarding None values.
Example:
input := A.From(OptionSome(1), OptionNone[int](), OptionSome(3), OptionSome(5), OptionNone[int]()) result := OptionCompactArray(input) // [1, 3, 5]
func OptionCompactArrayG ¶ added in v2.3.120
OptionCompactArrayG 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 := A.From(OptionSome(1), OptionNone[int](), OptionSome(3))
result := OptionCompactArrayG[[]Option[int], MySlice](input) // MySlice{1, 3}
func OptionFold ¶ added in v2.3.120
OptionFold 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 is Some.
Example:
handler := OptionFold(
func() string { return "no value" },
func(x int) string { return fmt.Sprintf("value: %d", x) },
)
result := handler(OptionSome(42)) // "value: 42"
result := handler(OptionNone[int]()) // "no value"
Relation to predicate.OptionFold:
option.OptionFold and predicate.OptionFold are two specialisations of the same categorical pattern — eliminating a two-case sum type into a common result type B.
option.Option[A] is a two-case sum type {None, OptionSome(A)}. The Some constructor carries a payload of type A, so the onSome branch receives it; the None branch carries no payload and is therefore a thunk:
option.OptionFold :: (() → B) → (A → B) → Option[A] → B
predicate.Predicate[A] is morally equivalent to A → bool, where bool is the smallest two-case sum type {false, true}. Because bool carries no payload beyond the branch tag, both handlers in predicate.OptionFold must receive A to preserve context:
predicate.OptionFold :: (A → B) → (A → B) → (A → bool) → A → B
The link between the two is FromPredicate, which converts a Predicate[A] into an Option[A]-producing function. Using it, predicate.OptionFold can always be expressed in terms of option.OptionFold:
predicate.OptionFold(onFalse, onTrue)(p)(a)
== option.OptionFold(func() B { return onFalse(a) }, onTrue)(FromPredicate(p)(a))
Conversely, option.OptionFold cannot in general be expressed via predicate.OptionFold because None carries no A value for the false branch to inspect.
See Also:
- MonadFold: The uncurried form of this function
- predicate.OptionFold: The analogous eliminator for the bool two-case sum type
- FromPredicate: Converts a Predicate[A] into a OptionKleisli[A, A] producing Option[A]
func OptionFromEq ¶ added in v2.3.120
func OptionFromEq[A any](pred eq.Eq[A]) func(A) OptionKleisli[A, A]
func OptionFromStrictEq ¶ added in v2.3.120
func OptionFromStrictEq[A comparable]() func(A) OptionKleisli[A, A]
func OptionGetOrElse ¶ added in v2.3.120
OptionGetOrElse returns a function that extracts the value from an Option or returns a default.
Example:
getOrZero := OptionGetOrElse(lazy.Of(0)) result := getOrZero(OptionSome(42)) // 42 result := getOrZero(OptionNone[int]()) // 0
func OptionIsNone ¶ added in v2.3.120
OptionIsNone checks if an Option is None (contains no value).
Example:
opt := OptionNone[int]() OptionIsNone(opt) // true opt := OptionSome(42) OptionIsNone(opt) // false
func OptionIsSome ¶ added in v2.3.120
OptionIsSome checks if an Option contains a value.
Example:
opt := OptionSome(42) OptionIsSome(opt) // true opt := OptionNone[int]() OptionIsSome(opt) // false
func OptionMonadFold ¶ added in v2.3.120
OptionMonadFold 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 := OptionSome(42)
result := OptionMonadFold(opt,
func() string { return "no value" },
func(x int) string { return fmt.Sprintf("value: %d", x) },
) // "value: 42"
func OptionMonadGetOrElse ¶ added in v2.3.120
OptionMonadGetOrElse extracts the value from an Option or returns a default value. This is the monadic form of GetOrElse.
Example:
result := OptionMonadGetOrElse(OptionSome(42), lazy.Of(0)) // 42 result := OptionMonadGetOrElse(OptionNone[int](), lazy.Of(0)) // 0
func OptionReduce ¶ added in v2.3.120
OptionReduce folds an Option into a single value using a reducer function. If the Option is None, returns the initial value.
Example:
sum := OptionReduce(func(acc, val int) int { return acc + val }, 0)
result := sum(OptionSome(5)) // 5
result := sum(OptionNone[int]()) // 0
func OptionSequence2 ¶ added in v2.3.120
func OptionSequence2[T1, T2, R any](f func(T1, T2) Option[R]) func(Option[T1], Option[T2]) Option[R]
OptionSequence2 returns a function that sequences two Options with a combining function.
Example:
add := OptionSequence2(func(a, b int) Option[int] { return OptionSome(a + b) })
result := add(OptionSome(2), OptionSome(3)) // OptionSome(5)
func OptionToNillable2 ¶ added in v2.3.120
OptionToNillable2 converts an Option[A] back to a nullable pointer. Returns a pointer to the contained value when the Option is Some, nil otherwise. This is the inverse of FromNillable2: round-tripping through both functions preserves the value but allocates a new pointer on each call.
Type Parameters:
- A: the type contained in the Option
Parameters:
- fa: the Option value to convert
Returns:
- a pointer to a copy of the contained value when fa is Some
- nil when fa is None
See Also:
- FromNillable2: the inverse — converts *A to Option[A]
func OptionUnwrap ¶ added in v2.3.120
OptionUnwrap 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 := OptionSome(42) val, ok := OptionUnwrap(opt) // val = 42, ok = true opt := OptionNone[int]() val, ok := OptionUnwrap(opt) // val = 0, ok = false
func OptionalAsTraversal ¶
func OptionalFromPredicate ¶
func OptionalFromPredicate[S, A any](pred func(A) bool) func(func(S) A, func(S, A) S) Optional[S, A]
OptionalFromPredicate creates an optional from getter and setter functions. It checks for optional values and the correct update procedure
func OptionalFromPredicateRef ¶
func OptionalFromPredicateRef[S, A any](pred func(A) bool) func(func(*S) A, func(*S, A) *S) Optional[*S, A]
FromPredicate creates an optional from getter and setter functions. It checks for optional values and the correct update procedure
func OptionalModifyOption ¶
func OptionalModifyOption[S, A any](f func(A) A) func(Optional[S, A]) OptionKleisli[S, S]
func OptionalSetOption ¶
func OptionalSetOption[S, A any](a A) func(Optional[S, A]) OptionKleisli[S, S]
func PrismAsTraversal ¶
func PrismAsTraversal[R ~func(func(A) HKTA) func(S) HKTS, S, A, HKTS, HKTA any]( fof pointed.OfType[S, HKTS], fmap functor.MapType[A, S, HKTA, HKTS], ) func(Prism[S, A]) R
PrismAsTraversal converts a Prism into a Traversal.
A Traversal is a more general optic that can focus on zero or more values, while a Prism focuses on zero or one value. This function lifts a Prism into the Traversal abstraction, allowing it to be used in contexts that expect traversals.
The conversion works by:
- If the prism matches (GetOption returns Some), the traversal focuses on that value
- If the prism doesn't match (GetOption returns None), the traversal focuses on zero values
Type Parameters:
- R: The traversal function type ~func(func(A) HKTA) func(S) HKTS
- S: The source type
- A: The focus type
- HKTS: Higher-kinded type for S (e.g., functor/applicative context)
- HKTA: Higher-kinded type for A (e.g., functor/applicative context)
Parameters:
- fof: Function to lift S into the higher-kinded type HKTS (pure/of operation)
- fmap: Function to map over HKTA and produce HKTS (functor map operation)
Returns:
- A function that converts a Prism[S, A] into a Traversal R
Example:
// Convert a prism to a traversal for use with applicative functors
prism := MakePrism(...)
traversal := AsTraversal(
func(s S) HKTS { return pure(s) },
func(hkta HKTA, f func(A) S) HKTS { return fmap(hkta, f) },
)(prism)
Note: This function is typically used in advanced scenarios involving higher-kinded types and applicative functors. Most users will work directly with prisms rather than converting them to traversals.
func PrismSet ¶
func PrismSet[S, A any](a A) func(Prism[S, A]) Endomorphism[S]
PrismSet creates a function that sets a value through a prism. If the prism matches, it replaces the focused value with the new value. If the prism doesn't match, it returns the original value unchanged.
Parameters:
- a: The new value to set
Returns:
- A function that takes a prism and returns an endomorphism (S → S)
Example:
somePrism := MakePrism(...) setter := PrismSet[Option[int], int](100) result := setter(somePrism)(Some(42)) // Some(100) result = setter(somePrism)(None[int]()) // None[int]() (unchanged)
Types ¶
type Endomorphism ¶
type Endomorphism[A any] = endomorphism.Endomorphism[A]
Endomorphism is a function from a type to itself (A → A). It represents transformations that preserve the type.
type Iso ¶
type Iso[S, A any] struct { // Get converts a value from the source type S to the target type A. Get func(s S) A // ReverseGet converts a value from the target type A back to the source type S. // This is the inverse of Get. ReverseGet func(a A) S // contains filtered or unexported fields }
Iso represents an isomorphism between types S and A. An isomorphism is a bidirectional transformation that converts between two types without any loss of information. It consists of two functions that are inverses of each other.
Type Parameters:
- S: The source type
- A: The target type
Fields:
- Get: Converts from S to A
- ReverseGet: Converts from A back to S
Laws: An Iso must satisfy the round-trip laws:
- ReverseGet(Get(s)) == s for all s: S
- Get(ReverseGet(a)) == a for all a: A
Example:
// Isomorphism between Celsius and Fahrenheit
tempIso := Iso[float64, float64]{
Get: func(c float64) float64 { return c*9/5 + 32 },
ReverseGet: func(f float64) float64 { return (f - 32) * 5 / 9 },
}
fahrenheit := tempIso.Get(20.0) // 68.0
celsius := tempIso.ReverseGet(68.0) // 20.0
func IsoId ¶
IsoId returns an identity isomorphism that performs no transformation. Both Get and ReverseGet are the identity function.
Type Parameters:
- S: The type for both source and target
Returns:
- An Iso[S, S] where Get and ReverseGet are both identity functions
Example:
idIso := IsoId[int]() value := idIso.Get(42) // 42 same := idIso.ReverseGet(42) // 42
Use cases:
- As a starting point for isomorphism composition
- When you need an isomorphism but don't want to transform the value
- In generic code that requires an isomorphism parameter
func IsoReverse ¶
IsoReverse swaps the direction of an isomorphism. Given Iso[S, A], creates Iso[A, S] where Get and ReverseGet are swapped.
Type Parameters:
- S: The original source type (becomes target)
- A: The original target type (becomes source)
Parameters:
- sa: The isomorphism to reverse
Returns:
- An Iso[A, S] with Get and ReverseGet swapped
Example:
celsiusToFahrenheit := MakeIso(
func(c float64) float64 { return c*9/5 + 32 },
func(f float64) float64 { return (f - 32) * 5 / 9 },
)
// IsoReverse to get Fahrenheit to Celsius
fahrenheitToCelsius := IsoReverse(celsiusToFahrenheit)
celsius := fahrenheitToCelsius.Get(68.0) // 20.0
fahrenheit := fahrenheitToCelsius.ReverseGet(20.0) // 68.0
func MakeIso ¶
MakeIso constructs an isomorphism from two functions. The functions should be inverses of each other to satisfy the isomorphism laws.
Type Parameters:
- S: The source type
- A: The target type
Parameters:
- get: Function to convert from S to A
- reverse: Function to convert from A to S (inverse of get)
Returns:
- An Iso[S, A] that uses the provided functions
Example:
// Create an isomorphism between string and []byte
stringBytesIso := MakeIso(
func(s string) []byte { return []byte(s) },
func(b []byte) string { return string(b) },
)
bytes := stringBytesIso.Get("hello") // []byte("hello")
str := stringBytesIso.ReverseGet([]byte("hi")) // "hi"
func (Iso[S, A]) Compose ¶
Compose returns a new isomorphism that focuses deeper by chaining this isomorphism (S → A) with an inner isomorphism (A → B), producing a composed isomorphism (S → B).
This is the method-receiver form of the package-level OptionalComposeOptional function, available only on Go 1.27 and later because Go did not support type parameters on methods before that version. On earlier toolchains, use the equivalent free function instead:
// method form (go1.27+) composed := outerIso.Compose(innerIso) // free-function form (all versions) composed := iso.Compose[S](innerIso)(outerIso)
Get of the composed isomorphism applies the outer Get followed by the inner Get: composed.Get(s) = ab.Get(sa.Get(s)).
ReverseGet of the composed isomorphism applies the inner ReverseGet followed by the outer ReverseGet: composed.ReverseGet(b) = sa.ReverseGet(ab.ReverseGet(b)).
The composed isomorphism satisfies both iso round-trip laws whenever both constituent isomorphisms individually satisfy them:
composed.ReverseGet(composed.Get(s)) == s for all s: S composed.Get(composed.ReverseGet(b)) == b for all b: B
Type Parameters:
- B: the target type of the inner isomorphism and of the resulting isomorphism
Parameters:
- ab: the inner isomorphism from A to B
Returns:
- Iso[S, B]: a new isomorphism from S directly to B
See Also:
- Compose: the equivalent package-level function
- Reverse: swaps the direction of an isomorphism
func (Iso[S, A]) ComposeLens ¶
ComposeLens returns a new lens by composing this isomorphism (S ↔ A) with an inner lens (A → B), producing a Lens[S, B].
Internally the isomorphism is first converted to a Lens[S, A] via IsoAsLens, then composed with the provided lens using LensComposeLens. The result focuses on a value of type B that is reached by first applying the isomorphism's Get direction and then the inner lens's Get.
This is the method-receiver form of the package-level IsoComposeLens function, available only on Go 1.27 and later because Go did not support type parameters on methods before that version. On earlier toolchains use the equivalent free function:
// method form (go1.27+) streetLens := addressIso.ComposeLens(streetFieldLens) // free-function form (all versions) streetLens := IsoComposeLens[S](streetFieldLens)(addressIso)
The resulting lens satisfies all three lens laws whenever both the isomorphism and the inner lens individually satisfy them.
Type Parameters:
- B: the focus type of the inner lens and of the resulting lens
Parameters:
- ab: the inner lens from A to B
Returns:
- Lens[S, B]: a new lens from S directly to B
See Also:
- Compose: the equivalent method for composing with an Iso[A, B] instead of a Lens[A, B]
- IsoComposeLens: the equivalent package-level function
type Lens ¶
type Lens[S, A any] struct { // Get extracts the focused value of type A from structure S. Get func(s S) A // Set returns a function that updates the focused value in structure S. // The returned function takes a structure S and returns a new structure S // with the focused value updated to a. The original structure is never modified. Set func(a A) Endomorphism[S] // contains filtered or unexported fields }
Lens is a functional reference to a subpart of a data structure.
A Lens[S, A] provides a composable way to focus on a field of type A within a structure of type S. It consists of two operations:
- Get: Extracts the focused value from the structure (S → A)
- Set: Updates the focused value in the structure, returning a new structure (A → S → S)
Lenses maintain immutability by always returning new copies of the structure when setting values, never modifying the original.
Type Parameters:
- S: The source/structure type (the whole)
- A: The focus/field type (the part)
Lens Laws:
A well-behaved lens must satisfy three laws:
- GetSet (You get what you set): lens.Set(lens.Get(s))(s) == s
- SetGet (You set what you get): lens.Get(lens.Set(a)(s)) == a
- SetSet (Setting twice is the same as setting once): lens.Set(a2)(lens.Set(a1)(s)) == lens.Set(a2)(s)
Example Usage:
type Person struct {
Name string
Age int
}
// Create a lens focusing on the Name field
nameLens := lens.MakeLens(
func(p Person) string { return p.Name },
func(name string) func(Person) Person {
return func(p Person) Person {
return Person{Name: name, Age: p.Age}
}
},
)
person := Person{Name: "Alice", Age: 30}
name := nameLens.Get(person) // Returns: "Alice"
updated := nameLens.Set("Bob")(person) // Returns: Person{Name: "Bob", Age: 30}
// Original person remains unchanged (immutability preserved)
func IsoAsLens ¶
IsoAsLens converts an Iso[S, A] into a Lens[S, A].
The resulting lens uses the iso's Get as its getter and its ReverseGet as its setter. Because an isomorphism is total and invertible, Set always replaces the focused value by applying ReverseGet — the original S is discarded.
Type Parameters:
- S: The source type of the isomorphism and of the resulting lens
- A: The target type of the isomorphism and the focus type of the resulting lens
Parameters:
- sa: The isomorphism to convert
Returns:
- Lens[S, A]: a lens whose Get is sa.Get and whose Set is sa.ReverseGet
See Also:
- IsoAsLensRef: the pointer-receiver variant for Iso[*S, A]
func IsoAsLensRef
deprecated
IsoAsLensRef converts an Iso[*S, A] into a Lens[*S, A] for pointer-based structures.
This is the pointer-receiver variant of IsoAsLens. It accepts an isomorphism whose source type is already a pointer (*S) and wraps the resulting lens with copy-on-write semantics: before the setter is applied, a shallow copy of *S is made so that the original value is never mutated. A nil pointer is handled safely by substituting a zero-value S.
In practice the copy-on-write wrapper is a no-op for an iso-derived setter, because the setter is simply ReverseGet(a) and ignores the incoming *S entirely. The wrapper exists for consistency with other pointer lenses and to guard against nil inputs.
Deprecated: IsoAsLens[*S, A] is sufficient because the copy-on-write wrapper added by this function has no observable effect for iso-derived setters. Prefer IsoAsLens unless you specifically need the nil-pointer safety on the incoming *S, which the iso's ReverseGet already cannot depend on.
Type Parameters:
- S: The pointee type; the isomorphism source is *S
- A: The target type of the isomorphism and the focus type of the resulting lens
Parameters:
- sa: The isomorphism from *S to A to convert
Returns:
- Lens[*S, A]: a lens whose Get is sa.Get and whose Set applies sa.ReverseGet with copy-on-write protection on the *S receiver
See Also:
- IsoAsLens: the general form that accepts any Iso[S, A], including Iso[*S, A]
func LensId ¶
LensId returns an identity Lens that focuses on the entire structure.
The identity lens is useful as a starting point for lens composition or when you need a lens that doesn't actually focus on a subpart. Get returns the structure unchanged, and Set replaces the entire structure.
Type Parameters:
- S: The structure type
Returns:
- A Lens[S, S] where both source and focus are the same type
Example:
type Person struct {
Name string
Age int
}
idLens := lens.LensId[Person]()
person := Person{Name: "Alice", Age: 30}
same := idLens.Get(person) // Returns person unchanged
replaced := idLens.Set(Person{Name: "Bob", Age: 25})(person)
// replaced is Person{Name: "Bob", Age: 25}
func LensIdRef ¶
LensIdRef returns an identity Lens for pointer-based structures.
This is the pointer version of LensId. It focuses on the entire pointer structure, with automatic copying to ensure immutability.
Type Parameters:
- S: The structure type (will be used as *S)
Returns:
- A Lens[*S, *S] where both source and focus are pointers to the same type
Example:
idLens := lens.LensIdRef[Person]()
person := &Person{Name: "Alice", Age: 30}
same := idLens.Get(person) // Returns person pointer
replaced := idLens.Set(&Person{Name: "Bob", Age: 25})(person)
// person.Name is still "Alice", replaced is a new pointer
func MakeLens ¶
MakeLens creates a Lens based on a getter and a setter F.
The setter must create a (shallow) copy of the data structure. This happens automatically when the data is passed by value. For pointer-based structures, use MakeLensRef instead. For other reference types (slices, maps), ensure the setter creates a copy.
Type Parameters:
- GET: Getter function type (S → A)
- SET: Setter function type (S, A → S)
- S: Source structure type
- A: Focus/field type
Parameters:
- get: Function to extract value A from structure S
- set: Function to update value A in structure S, returning a new S
Returns:
- A Lens[S, A] that can get and set values immutably
Example:
type Person struct {
Name string
Age int
}
nameLens := lens.MakeLens(
func(p Person) string { return p.Name },
func(p Person, name string) Person {
p.Name = name
return p
},
)
person := Person{Name: "Alice", Age: 30}
name := nameLens.Get(person) // "Alice"
updated := nameLens.Set("Bob")(person) // Person{Name: "Bob", Age: 30}
func MakeLensCurried ¶
func MakeLensCurried[GET ~func(S) A, SET ~func(A) Endomorphism[S], S, A any](get GET, set SET) Lens[S, A]
MakeLensCurried creates a Lens with a curried setter F.
This is similar to MakeLens but accepts a curried setter (A → S → S) instead of an uncurried one (S, A → S). The curried form is more composable in functional pipelines.
The setter must create a (shallow) copy of the data structure. This happens automatically when the data is passed by value. For pointer-based structures, use MakeLensRefCurried.
Type Parameters:
- GET: Getter function type (S → A)
- SET: Curried setter function type (A → S → S)
- S: Source structure type
- A: Focus/field type
Parameters:
- get: Function to extract value A from structure S
- set: Curried function to update value A in structure S
Returns:
- A Lens[S, A] that can get and set values immutably
Example:
nameLens := lens.MakeLensCurried(
func(p Person) string { return p.Name },
func(name string) func(Person) Person {
return func(p Person) Person {
p.Name = name
return p
}
},
)
func MakeLensCurriedRefWithName ¶
func MakeLensCurriedRefWithName[GET ~func(*S) A, SET ~func(A) Endomorphism[*S], S, A any](get GET, set SET, name string) Lens[*S, A]
MakeLensCurriedRefWithName creates a Lens for pointer-based structures with a curried setter and a custom name.
This is the named variant of MakeLensCurriedRefWithName combined with automatic copy-on-write semantics for pointer receivers. The setter does not need to create a copy manually; the copy is applied by the wrapped curried setter produced by setCopyCurried. The name is used in String, Format, and LogValue for debugging and structured logging.
Type Parameters:
- GET: Getter function type (*S → A)
- SET: Curried setter function type (A → *S → *S)
- S: Source structure type (will be used as *S)
- A: Focus/field type
Parameters:
- get: Function to extract value A from pointer *S
- set: Curried function to update value A in pointer *S (copying handled automatically)
- name: A descriptive name for the lens (used in String() and Format())
Returns:
- A Lens[*S, A] with the specified name
func MakeLensCurriedWithName ¶
func MakeLensCurriedWithName[GET ~func(S) A, SET ~func(A) Endomorphism[S], S, A any](get GET, set SET, name string) Lens[S, A]
MakeLensCurriedWithName creates a Lens with a curried setter and a custom name.
This combines the benefits of MakeLensCurried (curried setter for better composition) with MakeLensWithName (custom name for debugging). The name is useful for debugging complex lens compositions and understanding which lens is being used in error messages or logs.
The setter must create a (shallow) copy of the data structure. This happens automatically when the data is passed by value. For pointer-based structures, use MakeLensRefCurried.
Type Parameters:
- GET: Getter function type (S → A)
- SET: Curried setter function type (A → S → S)
- S: Source structure type
- A: Focus/field type
Parameters:
- get: Function to extract value A from structure S
- set: Curried function to update value A in structure S
- name: A descriptive name for the lens (used in String() and Format())
Returns:
- A Lens[S, A] with the specified name
Example:
type Person struct {
Name string
Age int
}
nameLens := lens.MakeLensCurriedWithName(
func(p Person) string { return p.Name },
func(name string) func(Person) Person {
return func(p Person) Person {
p.Name = name
return p
}
},
"Person.Name",
)
fmt.Printf("Using lens: %s\n", nameLens) // Prints: "Using lens: Person.Name"
func MakeLensRef ¶
MakeLensRef creates a Lens for pointer-based structures.
Unlike MakeLens, the setter does not need to create a copy manually. This function automatically wraps the setter to create a shallow copy of the pointed-to value before modification, ensuring immutability.
This lens assumes that property A always exists in structure S (i.e., it's not optional).
Type Parameters:
- GET: Getter function type (*S → A)
- SET: Setter function type (*S, A → *S)
- S: Source structure type (will be used as *S)
- A: Focus/field type
Parameters:
- get: Function to extract value A from pointer *S
- set: Function to update value A in pointer *S (copying handled automatically)
Returns:
- A Lens[*S, A] that can get and set values immutably on pointers
Example:
type Person struct {
Name string
Age int
}
nameLens := lens.MakeLensRef(
func(p *Person) string { return p.Name },
func(p *Person, name string) *Person {
p.Name = name // No manual copy needed
return p
},
)
person := &Person{Name: "Alice", Age: 30}
updated := nameLens.Set("Bob")(person)
// person.Name is still "Alice", updated is a new pointer with Name "Bob"
func MakeLensRefCurried ¶
func MakeLensRefCurried[S, A any](get func(*S) A, set func(A) Endomorphism[*S]) Lens[*S, A]
MakeLensRefCurried creates a Lens for pointer-based structures with a curried setter.
This combines the benefits of MakeLensRef (automatic copying) with MakeLensCurried (curried setter for better composition). The setter does not need to create a copy manually; this function automatically wraps it to ensure immutability.
This lens assumes that property A always exists in structure S (i.e., it's not optional).
Type Parameters:
- S: Source structure type (will be used as *S)
- A: Focus/field type
Parameters:
- get: Function to extract value A from pointer *S
- set: Curried function to update value A in pointer *S (copying handled automatically)
Returns:
- A Lens[*S, A] that can get and set values immutably on pointers
Example:
nameLens := lens.MakeLensRefCurried(
func(p *Person) string { return p.Name },
func(name string) func(*Person) *Person {
return func(p *Person) *Person {
p.Name = name // No manual copy needed
return p
}
},
)
func MakeLensRefCurriedWithName ¶
func MakeLensRefCurriedWithName[S, A any](get func(*S) A, set func(A) Endomorphism[*S], name string) Lens[*S, A]
MakeLensRefCurriedWithName creates a Lens for pointer-based structures with a curried setter and custom name.
This combines the benefits of MakeLensRefCurried (automatic copying with curried setter) with MakeLensWithName (custom name for debugging). The setter does not need to create a copy manually; this function automatically wraps it to ensure immutability. The curried form is more composable in functional pipelines, and the name is useful for debugging.
This lens assumes that property A always exists in structure S (i.e., it's not optional).
Type Parameters:
- S: Source structure type (will be used as *S)
- A: Focus/field type
Parameters:
- get: Function to extract value A from pointer *S
- set: Curried function to update value A in pointer *S (copying handled automatically)
- name: A descriptive name for the lens (used in String() and Format())
Returns:
- A Lens[*S, A] with the specified name
Example:
type Person struct {
Name string
Age int
}
nameLens := lens.MakeLensRefCurriedWithName(
func(p *Person) string { return p.Name },
func(name string) func(*Person) *Person {
return func(p *Person) *Person {
p.Name = name // No manual copy needed
return p
}
},
"Person.Name",
)
person := &Person{Name: "Alice", Age: 30}
fmt.Printf("Using lens: %s\n", nameLens) // Prints: "Using lens: Person.Name"
updated := nameLens.Set("Bob")(person)
// person.Name is still "Alice", updated is a new pointer with Name "Bob"
func MakeLensRefWithName ¶
func MakeLensRefWithName[GET ~func(*S) A, SET func(*S, A) *S, S, A any](get GET, set SET, name string) Lens[*S, A]
MakeLensRefWithName creates a Lens for pointer-based structures with a custom name.
This combines MakeLensRef (automatic copying for pointer structures) with MakeLensWithName (custom name for debugging). The setter does not need to create a copy manually; this function automatically wraps it to ensure immutability. The name is useful for debugging complex lens compositions and understanding which lens is being used in error messages or logs.
This lens assumes that property A always exists in structure S (i.e., it's not optional).
Type Parameters:
- GET: Getter function type (*S → A)
- SET: Setter function type (*S, A → *S)
- S: Source structure type (will be used as *S)
- A: Focus/field type
Parameters:
- get: Function to extract value A from pointer *S
- set: Function to update value A in pointer *S (copying handled automatically)
- name: A descriptive name for the lens (used in String() and Format())
Returns:
- A Lens[*S, A] with the specified name
Example:
type Person struct {
Name string
Age int
}
nameLens := lens.MakeLensRefWithName(
func(p *Person) string { return p.Name },
func(p *Person, name string) *Person {
p.Name = name // No manual copy needed
return p
},
"Person.Name",
)
person := &Person{Name: "Alice", Age: 30}
fmt.Printf("Using lens: %s\n", nameLens) // Prints: "Using lens: Person.Name"
updated := nameLens.Set("Bob")(person)
// person.Name is still "Alice", updated is a new pointer with Name "Bob"
func MakeLensStrict ¶
func MakeLensStrict[GET ~func(*S) A, SET func(*S, A) *S, S any, A comparable](get GET, set SET) Lens[*S, A]
MakeLensStrict creates a Lens for pointer-based structures with strict equality optimization.
This is a convenience function that combines MakeLensWithEq with strict equality comparison (==). It's suitable for comparable types (primitives, strings, pointers, etc.) and provides the same optimization as MakeLensWithEq: if the new value equals the current value, the original pointer is returned unchanged instead of creating a copy.
The setter does not need to create a copy manually; this function automatically wraps it to ensure immutability when changes are made.
This lens assumes that property A always exists in structure S (i.e., it's not optional).
Type Parameters:
- GET: Getter function type (*S → A)
- SET: Setter function type (*S, A → *S)
- S: Source structure type (will be used as *S)
- A: Focus/field type (must be comparable)
Parameters:
- get: Function to extract value A from pointer *S
- set: Function to update value A in pointer *S (copying handled automatically)
Returns:
- A Lens[*S, A] that can get and set values immutably on pointers with strict equality optimization
Example:
type Person struct {
Name string
Age int
}
// Using MakeLensStrict for a string field (comparable type)
nameLens := lens.MakeLensStrict(
func(p *Person) string { return p.Name },
func(p *Person, name string) *Person {
p.Name = name // No manual copy needed
return p
},
)
person := &Person{Name: "Alice", Age: 30}
// Setting the same value returns the original pointer (no copy)
same := nameLens.Set("Alice")(person)
// same == person (same pointer)
// Setting a different value creates a new copy
updated := nameLens.Set("Bob")(person)
// person.Name is still "Alice", updated is a new pointer with Name "Bob"
func MakeLensStrictWithName ¶
func MakeLensStrictWithName[GET ~func(*S) A, SET func(*S, A) *S, S any, A comparable](get GET, set SET, name string) Lens[*S, A]
MakeLensStrictWithName creates a Lens for pointer-based structures with strict equality optimization and a custom name.
This combines MakeLensStrict (strict equality optimization using ==) with MakeLensWithName (custom name for debugging). It's a convenience function suitable for comparable types (primitives, strings, pointers, etc.). If the new value equals the current value, the original pointer is returned unchanged instead of creating a copy. The name is useful for debugging.
The setter does not need to create a copy manually; this function automatically wraps it to ensure immutability when changes are made.
This lens assumes that property A always exists in structure S (i.e., it's not optional).
Type Parameters:
- GET: Getter function type (*S → A)
- SET: Setter function type (*S, A → *S)
- S: Source structure type (will be used as *S)
- A: Focus/field type (must be comparable)
Parameters:
- get: Function to extract value A from pointer *S
- set: Function to update value A in pointer *S (copying handled automatically)
- name: A descriptive name for the lens (used in String() and Format())
Returns:
- A Lens[*S, A] with strict equality optimization and the specified name
Example:
type Person struct {
Name string
Age int
}
// Using MakeLensStrictWithName for a string field (comparable type)
nameLens := lens.MakeLensStrictWithName(
func(p *Person) string { return p.Name },
func(p *Person, name string) *Person {
p.Name = name // No manual copy needed
return p
},
"Person.Name",
)
person := &Person{Name: "Alice", Age: 30}
fmt.Printf("Using lens: %s\n", nameLens) // Prints: "Using lens: Person.Name"
// Setting the same value returns the original pointer (no copy)
same := nameLens.Set("Alice")(person) // same == person
// Setting a different value creates a new copy
updated := nameLens.Set("Bob")(person) // person.Name still "Alice"
func MakeLensWithEq ¶
func MakeLensWithEq[GET ~func(*S) A, SET func(*S, A) *S, S, A any](pred EQ.Eq[A], get GET, set SET) Lens[*S, A]
MakeLensWithEq creates a Lens for pointer-based structures with equality optimization.
This is similar to MakeLensRef but includes an optimization: if the new value equals the current value (according to the provided Eq predicate), the original pointer is returned unchanged instead of creating a copy. This can improve performance and reduce allocations when setting values that don't actually change the structure.
The setter does not need to create a copy manually; this function automatically wraps it to ensure immutability when changes are made.
This lens assumes that property A always exists in structure S (i.e., it's not optional).
Type Parameters:
- GET: Getter function type (*S → A)
- SET: Setter function type (*S, A → *S)
- S: Source structure type (will be used as *S)
- A: Focus/field type
Parameters:
- pred: Equality predicate to compare values of type A
- get: Function to extract value A from pointer *S
- set: Function to update value A in pointer *S (copying handled automatically)
Returns:
- A Lens[*S, A] that can get and set values immutably on pointers with equality optimization
Example:
type Person struct {
Name string
Age int
}
nameLens := lens.MakeLensWithEq(
eq.FromStrictEquals[string](),
func(p *Person) string { return p.Name },
func(p *Person, name string) *Person {
p.Name = name // No manual copy needed
return p
},
)
person := &Person{Name: "Alice", Age: 30}
// Setting the same value returns the original pointer (no copy)
same := nameLens.Set("Alice")(person)
// same == person (same pointer)
// Setting a different value creates a new copy
updated := nameLens.Set("Bob")(person)
// person.Name is still "Alice", updated is a new pointer with Name "Bob"
func MakeLensWithEqWithName ¶
func MakeLensWithEqWithName[GET ~func(*S) A, SET func(*S, A) *S, S, A any](pred EQ.Eq[A], get GET, set SET, name string) Lens[*S, A]
MakeLensWithEqWithName creates a Lens for pointer-based structures with equality optimization and a custom name.
This combines MakeLensWithEq (equality optimization) with MakeLensWithName (custom name for debugging). If the new value equals the current value (according to the provided Eq predicate), the original pointer is returned unchanged instead of creating a copy. The name is useful for debugging complex lens compositions.
The setter does not need to create a copy manually; this function automatically wraps it to ensure immutability when changes are made.
This lens assumes that property A always exists in structure S (i.e., it's not optional).
Type Parameters:
- GET: Getter function type (*S → A)
- SET: Setter function type (*S, A → *S)
- S: Source structure type (will be used as *S)
- A: Focus/field type
Parameters:
- pred: Equality predicate to compare values of type A
- get: Function to extract value A from pointer *S
- set: Function to update value A in pointer *S (copying handled automatically)
- name: A descriptive name for the lens (used in String() and Format())
Returns:
- A Lens[*S, A] with equality optimization and the specified name
Example:
type Person struct {
Name string
Age int
}
nameLens := lens.MakeLensWithEqWithName(
eq.FromStrictEquals[string](),
func(p *Person) string { return p.Name },
func(p *Person, name string) *Person {
p.Name = name // No manual copy needed
return p
},
"Person.Name",
)
person := &Person{Name: "Alice", Age: 30}
fmt.Printf("Using lens: %s\n", nameLens) // Prints: "Using lens: Person.Name"
// Setting the same value returns the original pointer (no copy)
same := nameLens.Set("Alice")(person) // same == person
// Setting a different value creates a new copy
updated := nameLens.Set("Bob")(person) // person.Name still "Alice"
func MakeLensWithName ¶
func MakeLensWithName[GET ~func(S) A, SET ~func(S, A) S, S, A any](get GET, set SET, name string) Lens[S, A]
MakeLensWithName creates a Lens with a custom name for debugging and logging.
This is identical to MakeLens but allows you to specify a name that will be used when the lens is printed or formatted. The name is useful for debugging complex lens compositions and understanding which lens is being used in error messages or logs.
The setter must create a (shallow) copy of the data structure. This happens automatically when the data is passed by value. For pointer-based structures, use MakeLensRef instead.
Type Parameters:
- GET: Getter function type (S → A)
- SET: Setter function type (S, A → S)
- S: Source structure type
- A: Focus/field type
Parameters:
- get: Function to extract value A from structure S
- set: Function to update value A in structure S, returning a new S
- name: A descriptive name for the lens (used in String() and Format())
Returns:
- A Lens[S, A] with the specified name
Example:
type Person struct {
Name string
Age int
}
nameLens := lens.MakeLensWithName(
func(p Person) string { return p.Name },
func(p Person, name string) Person {
p.Name = name
return p
},
"Person.Name",
)
fmt.Printf("Using lens: %s\n", nameLens) // Prints: "Using lens: Person.Name"
func (Lens[S, A]) Compose ¶
Compose returns a new lens that focuses deeper into the structure by chaining this lens (S → A) with an inner lens (A → B), producing a composed lens (S → B).
This is the method-receiver form of the package-level IsoComposeIso function, available only on Go 1.27 and later because Go did not support type parameters on methods before that version. On earlier toolchains, use the equivalent free function instead:
// method form (go1.27+) personStreetLens := addressLens.Compose(streetLens) // free-function form (all versions) personStreetLens := lens.Compose[Person](streetLens)(addressLens)
The composed lens satisfies all three lens laws whenever both constituent lenses individually satisfy them.
Type Parameters:
- B: the focus type of the inner lens and of the resulting lens
Parameters:
- ab: the inner lens from A to B
Returns:
- Lens[S, B]: a new lens from S directly to B
See Also:
- Compose: the equivalent package-level function
func (Lens[S, A]) ComposeIso ¶
ComposeIso returns a new lens that focuses on a value of type B by composing this lens (S → A) with an isomorphism (A ↔ B), producing a lens (S → B).
This is the method-receiver form of the package-level LensComposeIso function, available only on Go 1.27 and later because Go did not support type parameters on methods before that version. On earlier toolchains use the equivalent free function:
// method form (go1.27+) fahrenheitLens := readingLens.ComposeIso(celsiusToFahrenheit) // free-function form (all versions) fahrenheitLens := LensComposeIso[Thermometer](celsiusToFahrenheit)(readingLens)
The resulting lens satisfies all three lens laws whenever both the outer lens and the isomorphism individually satisfy them.
Type Parameters:
- B: the focus type of the resulting lens — the target type of the isomorphism
Parameters:
- ab: the isomorphism from A to B
Returns:
- Lens[S, B]: a new lens from S directly to B
See Also:
- Compose: the equivalent method for composing with a Lens[A, B] instead of an Iso[A, B]
- LensComposeIso: the equivalent package-level function
func (Lens) Format ¶
Format implements fmt.Formatter.
Supports all standard format verbs:
- %s, %v, %+v, %q, and all other verbs: uses the String() representation (the lens name)
The exact output format is not a stable contract and may change across versions.
func (Lens) LogValue ¶
LogValue implements slog.LogValuer.
Returns a slog.Value that represents the lens for structured logging. The lens name is logged as a string value. The exact structure of the returned slog.Value is not a stable contract and may change across versions.
func (Lens[S, A]) Modify ¶
func (la Lens[S, A]) Modify(f Endomorphism[A]) Endomorphism[S]
Modify applies a transformation function to the value focused by the lens.
This method transforms the focused value within a structure by applying an endomorphism (a function from A to A) and returns a new structure with the transformed value. The transformation is applied by first getting the current value, applying the function, and then setting the result back into the structure.
Type Parameters:
- S: The structure type containing the focused value
- A: The type of the focused value
Parameters:
- f: An endomorphism that transforms the focused value
Returns:
- An endomorphism on S that applies the transformation
Example:
type Person struct {
Name string
Age int
}
ageLens := lens.MakeLens(
func(p Person) int { return p.Age },
func(p Person, age int) Person { p.Age = age; return p },
)
person := Person{Name: "Alice", Age: 30}
incrementAge := ageLens.Modify(func(age int) int { return age + 1 })
older := incrementAge(person)
// older.Age == 31, person.Age == 30 (original unchanged)
See Also:
- Modify: Package-level function for use in pipelines
- Set: For setting a constant value instead of transforming
type LensKleisli ¶
LensKleisli represents a function that takes a value of type A and returns a Lens[S, B]. This is useful for composing lenses in a monadic style, allowing for dynamic lens creation based on input values.
Type Parameters:
- S: The source/structure type
- A: The input type
- B: The focus type of the resulting lens
type LensOperator ¶
type LensOperator[S, A, B any] = LensKleisli[S, Lens[S, A], B]
LensOperator is a specialized Kleisli that takes a Lens[S, A] and returns a Lens[S, B]. This enables lens transformations and compositions where one lens is used to derive another.
Type Parameters:
- S: The source/structure type
- A: The focus type of the input lens
- B: The focus type of the resulting lens
func LensComposeIso ¶
LensComposeIso converts a Lens to a property of `A` into a lens to a property of type `B` the transformation is done via an ISO
func LensComposeLens ¶
LensComposeLens combines two lenses to focus on a deeply nested field.
Given a lens from S to A and a lens from A to B, LensComposeLens creates a lens from S to B. This allows you to navigate through nested structures in a composable way.
The composition follows the mathematical property: (sa ∘ ab).Get = ab.Get ∘ sa.Get
Type Parameters:
- S: Outer structure type
- A: Intermediate structure type
- B: Inner focus type
Parameters:
- ab: Lens from A to B (inner lens)
Returns:
- A function that takes a Lens[S, A] and returns a Lens[S, B]
Example:
type Address struct {
Street string
City string
}
type Person struct {
Name string
Address Address
}
addressLens := lens.MakeLens(
func(p Person) Address { return p.Address },
func(p Person, a Address) Person { p.Address = a; return p },
)
streetLens := lens.MakeLens(
func(a Address) string { return a.Street },
func(a Address, s string) Address { a.Street = s; return a },
)
// LensComposeLens to access street directly from person
personStreetLens := F.Pipe1(addressLens, lens.LensComposeLens[Person](streetLens))
person := Person{Name: "Alice", Address: Address{Street: "Main St"}}
street := personStreetLens.Get(person) // "Main St"
updated := personStreetLens.Set("Oak Ave")(person)
func LensComposeLensRef
deprecated
LensComposeLensRef combines two lenses for pointer-based structures.
Deprecated: LensComposeLensRef is not needed. When the outer lens is already a pointer lens (Lens[*S, A], created with MakeLensRef or MakeLensRefCurried), its Set implementation already copies *S before writing. The copy that LensComposeLensRef adds via MakeLensRefCurriedWithName is therefore redundant — the composed setter calls the outer lens's Set, which copies, so the original pointer is never mutated.
Use LensComposeLens[*S] instead:
// Before personStreetLens := F.Pipe1(addressLens, lens.LensComposeLensRef[Person](streetLens)) // After — identical behaviour, no extra copy personStreetLens := F.Pipe1(addressLens, lens.Compose[*Person](streetLens))
Type Parameters:
- S: Outer structure type (will be used as *S)
- A: Intermediate structure type
- B: Inner focus type
Parameters:
- ab: Lens from A to B (inner lens)
Returns:
- A function that takes a Lens[*S, A] and returns a Lens[*S, B]
func LensIMap ¶
LensIMap transforms the focus type of a lens using an isomorphism.
An isomorphism is a pair of functions (A → B, B → A) that are inverses of each other. LensIMap allows you to work with a lens in a different but equivalent type. This is useful for unit conversions, encoding/decoding, or any bidirectional transformation.
Type Parameters:
- E: Structure type
- AB: Forward transformation function type (A → B)
- BA: Backward transformation function type (B → A)
- A: Original focus type
- B: Transformed focus type
Parameters:
- ab: Forward transformation (A → B)
- ba: Backward transformation (B → A)
Returns:
- A function that takes a Lens[E, A] and returns a Lens[E, B]
Example:
type Celsius float64
type Fahrenheit float64
celsiusToFahrenheit := func(c Celsius) Fahrenheit {
return Fahrenheit(c*9/5 + 32)
}
fahrenheitToCelsius := func(f Fahrenheit) Celsius {
return Celsius((f - 32) * 5 / 9)
}
type Weather struct {
Temperature Celsius
}
tempCelsiusLens := lens.MakeLens(
func(w Weather) Celsius { return w.Temperature },
func(w Weather, t Celsius) Weather { w.Temperature = t; return w },
)
// Create a lens that works with Fahrenheit
tempFahrenheitLens := F.Pipe1(
tempCelsiusLens,
lens.LensIMap[Weather](celsiusToFahrenheit, fahrenheitToCelsius),
)
weather := Weather{Temperature: 20} // 20°C
tempF := tempFahrenheitLens.Get(weather) // 68°F
updated := tempFahrenheitLens.Set(86)(weather) // Set to 86°F (30°C)
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
func OptionFlatten ¶ added in v2.3.120
OptionFlatten removes one level of nesting from a nested Option.
Example:
nested := OptionSome(OptionSome(42)) result := OptionFlatten(nested) // OptionSome(42) nested := OptionSome(OptionNone[int]()) result := OptionFlatten(nested) // None
func OptionFromNillable
deprecated
added in
v2.3.120
OptionFromNillable converts a pointer to an Option wrapping the pointer itself. Returns OptionSome(*A) when the pointer is non-nil, None otherwise.
Deprecated: Use FromNillable2 instead. FromNillable2 unwraps the pointed-to value into an Option[A], which is the more useful form: it avoids carrying a *A inside the Option and composes naturally with the rest of the Option API.
func OptionFromNillable2 ¶ added in v2.3.120
OptionFromNillable2 converts a pointer to an Option of the pointed-to value. Returns OptionSome(value) when the pointer is non-nil (dereferencing it), None otherwise. This is the preferred alternative to FromNillable because the resulting Option[A] composes naturally with Map, Chain, and the rest of the Option API without having to deal with an intermediate pointer inside the Option.
Type Parameters:
- A: the type that the pointer points to
Parameters:
- a: a pointer to a value of type A; may be nil
Returns:
- OptionSome(*a) when a is non-nil
- None when a is nil
See Also:
- ToNillable2: the inverse — converts Option[A] back to *A
- FromNillable: the older variant that wraps the pointer itself as Option[*A]
func OptionInstanceOf ¶ added in v2.3.120
OptionInstanceOf 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 := OptionInstanceOf[int](x) // Some(42) var y any = "hello" result := OptionInstanceOf[int](y) // None (wrong type)
func OptionMonadAlt ¶ added in v2.3.120
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(OptionSome(5), func() Option[int] { return OptionSome(10) }) // OptionSome(5)
result := MonadAlt(OptionNone[int](), func() Option[int] { return OptionSome(10) }) // OptionSome(10)
func OptionMonadAp ¶ added in v2.3.120
OptionMonadAp 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 := OptionSome(N.Mul(2)) fa := OptionSome(5) result := OptionMonadAp(fab, fa) // OptionSome(10)
func OptionMonadChain ¶ added in v2.3.120
func OptionMonadChain[A, B any](fa Option[A], f OptionKleisli[A, B]) Option[B]
OptionMonadChain 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 := OptionSome(5) result := OptionMonadChain(fa, F.Flow2(Predicate(N.MoreThan(0)), Map(N.Mul(2)))) // OptionSome(10)
func OptionMonadChainFirst ¶ added in v2.3.120
func OptionMonadChainFirst[A, B any](ma Option[A], f OptionKleisli[A, B]) Option[A]
OptionMonadChainFirst applies a function that returns an Option but keeps the original value. If either operation results in None, returns None.
Example:
result := OptionMonadChainFirst(OptionSome(5), func(x int) Option[string] {
return OptionSome(fmt.Sprintf("%d", x))
}) // OptionSome(5) - original value is kept
func OptionMonadChainTo ¶ added in v2.3.120
OptionMonadChainTo ignores the first Option and returns the second Option. Useful for sequencing operations where the first result is not needed.
Example:
result := OptionMonadChainTo(OptionSome(5), OptionSome("hello")) // OptionSome("hello")
func OptionMonadFlap ¶ added in v2.3.120
OptionMonadFlap applies a value to a function wrapped in an Option. This is the monadic form of Flap.
Example:
fab := OptionSome(N.Mul(2)) result := OptionMonadFlap(fab, 5) // OptionSome(10)
func OptionMonadMap ¶ added in v2.3.120
OptionMonadMap 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 := OptionSome(5) result := OptionMonadMap(fa, N.Mul(2)) // OptionSome(10)
func OptionMonadMapTo ¶ added in v2.3.120
OptionMonadMapTo 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 := OptionSome(5)
result := OptionMonadMapTo(fa, "hello") // OptionSome("hello")
func OptionMonadSequence2 ¶ added in v2.3.120
func OptionMonadSequence2[T1, T2, R any](o1 Option[T1], o2 Option[T2], f func(T1, T2) Option[R]) Option[R]
OptionMonadSequence2 sequences two Options and applies a function to their values. Returns None if either Option is None.
Example:
result := OptionMonadSequence2(OptionSome(2), OptionSome(3), func(a, b int) Option[int] {
return OptionSome(a + b)
}) // OptionSome(5)
func OptionNone ¶ added in v2.3.120
OptionNone creates an Option that contains no value.
Example:
opt := OptionNone[int]() // Empty Option of type int opt := OptionNone[string]() // Empty Option of type string
func OptionOf ¶ added in v2.3.120
OptionOf creates an Option that contains a value. This is an alias for OptionSome and is used in monadic contexts.
Example:
opt := OptionOf(42) // Option containing 42
func OptionSequenceArray ¶ added in v2.3.120
OptionSequenceArray 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 := OptionSequenceArray(A.From(OptionSome(1), OptionSome(2), OptionSome(3))) // OptionSome([1, 2, 3]) result := OptionSequenceArray(A.From(OptionSome(1), OptionNone[int](), OptionSome(3))) // None
func OptionSequenceArrayG ¶ added in v2.3.120
OptionSequenceArrayG 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 := OptionSequenceArrayG[MySlice](A.From(OptionSome(1), OptionSome(2))) // OptionSome(MySlice{1, 2})
result := OptionSequenceArrayG[MySlice](A.From(OptionSome(1), OptionNone[int]())) // None
func OptionSome ¶ added in v2.3.120
OptionSome creates an Option that contains a value.
Example:
opt := OptionSome(42) // Option containing 42
opt := OptionSome("hello") // Option containing "hello"
func OptionToAny ¶ added in v2.3.120
OptionToAny converts a value of any type to Option[any]. This always succeeds and returns Some containing the value as any.
Example:
result := OptionToAny(42) // Some(any(42))
result := OptionToAny("hello") // Some(any("hello"))
func OptionTryCatch ¶ added in v2.3.120
OptionTryCatch executes a function that may return an error and converts the result to an Option. Returns OptionSome(value) if no error occurred, None if an error occurred.
Example:
result := OptionTryCatch(func() (int, error) {
return strconv.Atoi("42")
}) // OptionSome(42)
func OptionZero ¶ added in v2.3.120
OptionZero returns the zero value of an Option, which is None. This function is useful as an identity element in monoid operations or for creating an empty Option.
The zero value for Option[A] is always None, representing the absence of a value. This is consistent with the Option monad's semantics where None represents "no value" and Some represents "a value".
Important: OptionZero() returns the same value as the default initialization of Option[A]. When you declare `var o Option[A]` without initialization, it has the same value as OptionZero[A]().
Note: Unlike other types where zero might be a default value, Option's zero is explicitly the absence of any value (None), not Some with a zero value.
Example:
// OptionZero Option of any type is always None o1 := option.OptionZero[int]() // None o2 := option.OptionZero[string]() // None o3 := option.OptionZero[*int]() // None // OptionZero equals default initialization var defaultInit Option[int] zero := option.OptionZero[int]() assert.Equal(t, defaultInit, zero) // true // Verify it's None o := option.OptionZero[int]() assert.True(t, option.IsNone(o)) // true assert.False(t, option.IsOptionSome(o)) // false // Different from Some with zero value someZero := option.OptionSome(0) // OptionSome(0) zero := option.OptionZero[int]() // None assert.NotEqual(t, someZero, zero) // they are different
func (Option[A]) Format ¶ added in v2.3.120
Format implements fmt.Formatter for Option. Supports all standard format verbs:
- %s, %v, %+v, %q, and all other verbs: uses String() representation
The exact output format is not a stable contract and may change across versions.
func (Option[A]) MarshalJSON ¶ added in v2.3.120
func (Option[A]) String ¶ added in v2.3.120
String implements fmt.Stringer for Option. Returns a human-readable string representation intended for debugging and logging. The exact format, including any package-path prefix that appears in %T output, is not a stable contract and may change across versions.
Example:
Some(42).String() // "Some[int](42)" None[int]().String() // "None[int]"
func (*Option[A]) UnmarshalJSON ¶ added in v2.3.120
type OptionKleisli ¶ added in v2.3.120
func OptionFromNonZero ¶ added in v2.3.120
func OptionFromNonZero[A comparable]() OptionKleisli[A, A]
func OptionFromPredicate ¶ added in v2.3.120
func OptionFromPredicate[A any](pred Predicate[A]) OptionKleisli[A, A]
OptionFromPredicate 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 := OptionFromPredicate(N.MoreThan(0)) result := isPositive(5) // OptionSome(5) result := isPositive(-1) // None
func OptionFromValidation ¶ added in v2.3.120
func OptionFromValidation[A, B any](f func(A) (B, bool)) OptionKleisli[A, B]
OptionFromValidation converts a validation function (returning value and bool) to an Option-returning function. This is an alias for Optionize1.
Example:
parseNum := OptionFromValidation(func(s string) (int, bool) {
n, err := strconv.Atoi(s)
return n, err == nil
})
result := parseNum("42") // OptionSome(42)
func OptionFromZero ¶ added in v2.3.120
func OptionFromZero[A comparable]() OptionKleisli[A, A]
func OptionOptionize1 ¶ added in v2.3.120
func OptionOptionize1[F ~func(T0) (R, bool), T0, R any](f F) OptionKleisli[T0, R]
OptionOptionize1 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 OptionTraverseArray ¶ added in v2.3.120
func OptionTraverseArray[A, B any](f OptionKleisli[A, B]) OptionKleisli[[]A, []B]
OptionTraverseArray 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 := F.Flow2(Predicate(N.MoreThan(0)), Map(N.Mul(2)))
result := OptionTraverseArray(validate)([]int{1, 2, 3}) // OptionSome([2, 4, 6])
result := OptionTraverseArray(validate)([]int{1, -1, 3}) // None
func OptionTraverseArrayG ¶ added in v2.3.120
func OptionTraverseArrayG[GA ~[]A, GB ~[]B, A, B any](f OptionKleisli[A, B]) OptionKleisli[GA, GB]
OptionTraverseArrayG 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 OptionNone[int]() }
return OptionSome(n)
}
result := OptionTraverseArrayG[[]string, []int](parse)([]string{"1", "2", "3"}) // OptionSome([1, 2, 3])
result := OptionTraverseArrayG[[]string, []int](parse)([]string{"1", "x", "3"}) // None
func OptionTraverseArrayWithIndex ¶ added in v2.3.120
func OptionTraverseArrayWithIndex[A, B any](f func(int, A) Option[B]) OptionKleisli[[]A, []B]
OptionTraverseArrayWithIndex 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 OptionSome(x) }
return OptionNone[int]()
}
result := OptionTraverseArrayWithIndex(f)([]int{1, 2, 3}) // OptionSome([1, 2, 3])
func OptionTraverseArrayWithIndexG ¶ added in v2.3.120
func OptionTraverseArrayWithIndexG[GA ~[]A, GB ~[]B, A, B any](f func(int, A) Option[B]) OptionKleisli[GA, GB]
OptionTraverseArrayWithIndexG 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 OptionSome(fmt.Sprintf("%d:%s", i, s))
}
result := OptionTraverseArrayWithIndexG[[]string, []string](f)([]string{"a", "b"}) // OptionSome(["0:a", "1:b"])
type OptionKleisliI ¶ added in v2.3.120
type OptionOperator ¶ added in v2.3.120
type OptionOperator[A, B any] = OptionKleisli[Option[A], B]
func OptionAlt ¶ added in v2.3.120
OptionAlt returns a function that provides an alternative Option if the input is None.
Example:
withDefault := OptionAlt(func() Option[int] { return OptionSome(0) })
result := withDefault(OptionSome(5)) // OptionSome(5)
result := withDefault(OptionNone[int]()) // OptionSome(0)
func OptionAp ¶ added in v2.3.120
OptionAp is the curried applicative functor for Option. Returns a function that applies an Option-wrapped function to the given Option value.
Example:
fa := OptionSome(5) applyTo5 := OptionAp[int](fa) fab := OptionSome(N.Mul(2)) result := applyTo5(fab) // OptionSome(10)
func OptionChain ¶ added in v2.3.120
func OptionChain[A, B any](f OptionKleisli[A, B]) OptionOperator[A, B]
OptionChain 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 := OptionChain(F.Flow2(Predicate(N.MoreThan(0)), Map(N.Mul(2)))) result := validate(OptionSome(5)) // OptionSome(10)
func OptionChainFirst ¶ added in v2.3.120
func OptionChainFirst[A, B any](f OptionKleisli[A, B]) OptionOperator[A, A]
OptionChainFirst returns a function that applies an Option-returning function but keeps the original value.
Example:
logAndKeep := OptionChainFirst(func(x int) Option[string] {
fmt.Println(x)
return OptionSome("logged")
})
result := logAndKeep(OptionSome(5)) // OptionSome(5)
func OptionChainOptionNone ¶ added in v2.3.120
ChainNone is the curried version that sequences a computation on the None (empty) value. Returns a function that applies the provided function when the Option is None, or returns None when the Option is Some.
Note: ChainNone is identical to Alt - both provide the same functionality for providing alternative values when an Option is None.
The naming convention follows the pattern established by ChainLeft in the Either type, where operations on the "error" or "empty" case use the Left/None suffix to distinguish them from operations on the "success" or "present" case (Chain operates on Some values, while ChainNone operates on None values).
This is useful for creating reusable default value providers or transformers that can be composed with other Option operations using pipes or function composition.
Example:
// Create a reusable default provider
provideDefault := option.ChainNone(func() option.Option[int] {
return option.OptionSome(42)
})
// Use in a pipeline
result := F.Pipe1(
option.OptionNone[int](),
provideDefault,
) // OptionSome(42)
// Some values pass through unchanged
result := F.Pipe1(
option.OptionSome(10),
provideDefault,
) // OptionSome(10)
func OptionChainTo ¶ added in v2.3.120
OptionChainTo returns a function that ignores its input Option and returns a fixed Option.
Example:
replaceWith := OptionChainTo(OptionSome("hello"))
result := replaceWith(OptionSome(42)) // OptionSome("hello")
func OptionFilter ¶ added in v2.3.120
func OptionFilter[A any](pred Predicate[A]) OptionOperator[A, A]
OptionFilter keeps the Option if it's Some and the predicate is satisfied, otherwise returns None.
Example:
isPositive := OptionFilter(N.MoreThan(0)) result := isPositive(OptionSome(5)) // OptionSome(5) result := isPositive(OptionSome(-1)) // None result := isPositive(OptionNone[int]()) // None
func OptionFlap ¶ added in v2.3.120
func OptionFlap[B, A any](a A) OptionOperator[func(A) B, B]
OptionFlap returns a function that applies a value to an Option-wrapped function.
Example:
applyFive := OptionFlap[int](5) fab := OptionSome(N.Mul(2)) result := applyFive(fab) // OptionSome(10)
func OptionMap ¶ added in v2.3.120
func OptionMap[A, B any](f func(a A) B) OptionOperator[A, B]
OptionMap returns a function that applies a transformation to the value inside an Option. If the Option is None, returns None.
Example:
double := OptionMap(N.Mul(2)) result := double(OptionSome(5)) // OptionSome(10) result := double(OptionNone[int]()) // None
func OptionMapTo ¶ added in v2.3.120
func OptionMapTo[A, B any](b B) OptionOperator[A, B]
OptionMapTo returns a function that replaces the value inside an Option with a constant.
Example:
replaceWith42 := OptionMapTo[string, int](42)
result := replaceWith42(OptionSome("hello")) // OptionSome(42)
type OptionTraversable ¶ added in v2.3.120
type OptionTraversable[A, B, GA, GB any] = func(OptionKleisli[A, B]) OptionKleisli[GA, GB]
OptionTraversable represents a data structure that can be traversed from left to right, applying an effectful function to each element and collecting the results.
A Traversable takes a Kleisli arrow (a function that returns an Option) and produces another Kleisli arrow that operates on a container of values.
Type Parameters:
- A: The input element type
- B: The output element type
- GA: The input container type (e.g., []A, map[K]A)
- GB: The output container type (e.g., []B, map[K]B)
The Traversable signature:
func(Kleisli[A, B]) Kleisli[GA, GB]
expands to:
func(func(A) Option[B]) func(GA) Option[GB]
This means: given a function that transforms A to Option[B], produce a function that transforms a container of A values into an Option of a container of B values.
Behavior:
- If all transformations succeed (return Some), the result is Some containing the container of all transformed values
- If any transformation fails (returns None), the entire result is None
Common Use Cases:
- Validating and transforming collections where any failure should fail the whole operation
- Parsing collections of strings where all must parse successfully
- Applying optional transformations across data structures
Example:
// Array traversable
traversable := TraversableArray[string, int]()
parse := func(s string) Option[int] {
n, err := strconv.Atoi(s)
if err != nil { return None[int]() }
return Some(n)
}
result := traversable(parse)([]string{"1", "2", "3"}) // Some([1, 2, 3])
result := traversable(parse)([]string{"1", "x", "3"}) // None
See Also:
- TraversableArray: Traversable instance for arrays
- TraverseArray: Direct array traversal function
- TraverseRecord: Traversal for maps/records
func OptionTraversableArray ¶ added in v2.3.120
func OptionTraversableArray[A, B any]() OptionTraversable[A, B, []A, []B]
OptionTraversableArray returns a Traversable instance for arrays. A Traversable represents a data structure that can be traversed from left to right, applying an effectful function to each element and collecting the results.
This function provides a way to obtain the traversal operation for arrays as a first-class value, which is useful when you need to pass the traversal operation as a parameter or compose it with other operations.
Type Parameters:
- A: The input element type
- B: The output element type
Returns:
- Traversable[A, B, []A, []B]: A function that takes a Kleisli arrow and returns another Kleisli arrow that operates on arrays
The returned Traversable has the signature:
func(OptionKleisli[A, B]) OptionKleisli[[]A, []B]
which is equivalent to:
func(func(A) Option[B]) func([]A) Option[[]B]
Example:
// Get the traversable instance
traversable := OptionTraversableArray[string, int]()
// Use it with a parsing function
parse := func(s string) Option[int] {
n, err := strconv.Atoi(s)
if err != nil { return OptionNone[int]() }
return OptionSome(n)
}
result := traversable(parse)([]string{"1", "2", "3"}) // OptionSome([1, 2, 3])
See Also:
- TraverseArray: Direct traversal without obtaining the Traversable instance
- TraverseArrayG: Generic version supporting custom slice types
type Optional ¶
type Optional[S, A any] struct { GetOption func(s S) Option[A] Set func(a A) EM.Endomorphism[S] // contains filtered or unexported fields }
Optional is an optional reference to a subpart of a data type
func MakeOptional ¶
func MakeOptional[S, A any](get OptionKleisli[S, A], set func(S, A) S) Optional[S, A]
MakeOptional creates an Optional based on a getter and a setter function. Make sure that the setter creates a (shallow) copy of the data. This happens automatically if the data is passed by value. For pointers consider to use `MakeOptionalRef` and for other kinds of data structures that are copied by reference make sure the setter creates the copy.
func MakeOptionalCurried ¶
func MakeOptionalCurried[S, A any](get OptionKleisli[S, A], set func(A) func(S) S) Optional[S, A]
func MakeOptionalCurriedWithName ¶
func MakeOptionalCurriedWithName[S, A any](get OptionKleisli[S, A], set func(A) func(S) S, name string) Optional[S, A]
func MakeOptionalRef ¶
func MakeOptionalRef[S, A any](get OptionKleisli[*S, A], set func(*S, A) *S) Optional[*S, A]
MakeOptionalRef creates an Optional based on a getter and a setter function. The setter passed in does not have to create a shallow copy, the implementation wraps the setter into one that copies the pointer before modifying it
func MakeOptionalRefCurriedWithName ¶
func MakeOptionalRefCurriedWithName[S, A any](get OptionKleisli[*S, A], set func(A) func(*S) *S, name string) Optional[*S, A]
func MakeOptionalRefWithName ¶
func MakeOptionalRefWithName[S, A any](get OptionKleisli[*S, A], set func(*S, A) *S, name string) Optional[*S, A]
func MakeOptionalWithName ¶
func MakeOptionalWithName[S, A any](get OptionKleisli[S, A], set func(S, A) S, name string) Optional[S, A]
func OptionalId ¶
OptionalId returns am optional implementing the identity operation
func OptionalIdRef ¶
Id returns am optional implementing the identity operation
func (Optional[S, A]) Compose ¶
Compose returns a new Optional that focuses deeper into a structure by chaining this optional (S → A) with an inner optional (A → B), producing a composed optional (S → B).
This is the method-receiver form of the package-level OptionalComposeOptional function, available only on Go 1.27 and later because Go did not support type parameters on methods before that version. On earlier toolchains, use the equivalent free function instead:
// method form (go1.27+) composed := outerOptional.Compose(innerOptional) // free-function form (all versions) composed := optional.Compose[S](innerOptional)(outerOptional)
GetOption of the composed optional chains the two GetOption functions: it first applies the outer optional to obtain an Option[A], then chains the inner optional through that option via O.Chain, returning None whenever either optional produces None.
Set of the composed optional updates the deeply nested focus by threading the new value back through the inner optional's Set and then propagating the change upward via the outer optional's Set. When either optional produces None, Set is a no-op and the original S is returned unchanged, consistent with the Optional no-op law.
The composed optional satisfies all three optional laws (GetSet, SetGet, SetSet) whenever both constituent optionals individually satisfy them.
Type Parameters:
- B: the focus type of the inner optional and of the resulting optional
Parameters:
- ab: the inner optional from A to B
Returns:
- Optional[S, B]: a new optional from S directly to B
See Also:
- Compose: the equivalent package-level function
- ComposeRef: variant for pointer-based outer structures
func (Optional) Format ¶
Format implements fmt.Formatter for Optional. Supports all standard format verbs:
- %s, %v, %+v, %q, and all other verbs: uses String() representation (optional name)
The exact output format is not a stable contract and may change across versions.
func (Optional) String ¶
func (o Optional) String() string
String returns the name of the optional for debugging and display purposes. The exact format is not a stable contract and may change across versions.
Example:
fieldOptional := optional.MakeOptionalWithName(..., "Person.Email") fmt.Println(fieldOptional) // Prints: "Person.Email"
type OptionalKleisli ¶
OptionalKleisli represents a function that takes a value of type A and returns an Optional[S, B]. This is commonly used for composing optionals in a monadic style.
Type Parameters:
- S: The source type of the resulting optional
- A: The input type to the function
- B: The focus type of the resulting optional
type OptionalOperator ¶
OptionalOperator represents a function that transforms one optional into another. It takes an Optional[S, A] and returns an Optional[S, B], allowing for optional transformations.
Type Parameters:
- S: The source type (remains constant)
- A: The original focus type
- B: The new focus type
func OptionalComposeOptional ¶
OptionalComposeOptional combines two Optional and allows to narrow down the focus to a sub-Optional
func OptionalComposeOptionalRef ¶
OptionalComposeOptionalRef combines two Optional and allows to narrow down the focus to a sub-Optional
func OptionalIChain ¶
func OptionalIChain[S, A, B any](ab OptionKleisli[A, B], ba OptionKleisli[B, A]) OptionalOperator[S, A, B]
OptionalIChain implements a bidirectional mapping of the transform if the transform can produce optionals (e.g. in case of type mappings)
func OptionalIChainAny ¶
OptionalIChainAny implements a bidirectional mapping to and from any
func OptionalIMap ¶
func OptionalIMap[S, A, B any](ab func(A) B, ba func(B) A) OptionalOperator[S, A, B]
OptionalIMap implements a bidirectional mapping of the transform
type Predicate ¶ added in v2.3.120
func OptionExists ¶ added in v2.3.120
OptionExists creates a predicate that tests whether an Option value is Some and its value satisfies the given predicate. It returns a function that takes an Option[T] and returns true only if the Option is Some and the predicate p returns true for the contained value.
This function is useful for checking if an Option contains a value that meets certain criteria, commonly used in filtering operations, validation chains, or conditional logic where you need to verify both the presence of a value and a property of that value.
The behavior is as follows:
- If the input is None, returns false (regardless of the predicate)
- If the input is Some and p returns true for the contained value, returns true
- If the input is Some and p returns false for the contained value, returns false
Type Parameters:
- T: The type of the value contained in the Option
Parameters:
- p: A predicate function that tests values of type T
Returns:
A Predicate function that takes an Option[T] and returns true if it's Some and satisfies p
Example:
import (
O "github.com/IBM/fp-go/v2/option"
N "github.com/IBM/fp-go/v2/number"
)
// Check if Option contains a positive number
isPositive := N.MoreThan(0)
hasPositive := O.OptionExists(isPositive)
result1 := hasPositive(O.Some(5))
// result1 = true (Some with positive value)
result2 := hasPositive(O.Some(-3))
// result2 = false (Some with non-positive value)
result3 := hasPositive(O.None[int]())
// result3 = false (None value)
// Use in filtering
values := []O.Option[int]{
O.Some(5),
O.None[int](),
O.Some(-3),
O.Some(10),
}
hasPositiveValue := func(opt O.Option[int]) bool {
return hasPositive(opt)
}
// Filter to keep only Options with positive Some values
// filtered would contain: [Some(5), Some(10)]
See Also:
- Filter: Converts Some values that fail a predicate to None
- IsSome: Tests if Option is Some without checking the value
func OptionForAll ¶ added in v2.3.120
OptionForAll creates a predicate that tests whether an Option value is None or its Some value satisfies the given predicate. It returns a function that takes an Option[T] and returns true if the Option is None (regardless of content) or if it's Some and the predicate p returns true for the contained value.
This function implements universal quantification over the Option type. In logical terms, it states: "for all values in the Option, the predicate holds" - which is vacuously true for None values (empty case) and requires the predicate to hold for Some values (non-empty case).
The behavior is as follows:
- If the input is None, returns true (vacuous truth - predicate holds for empty case)
- If the input is Some and p returns true for the contained value, returns true
- If the input is Some and p returns false for the contained value, returns false
Relationship to Haskell and Category Theory:
In Haskell, this corresponds to the all function for the Maybe type when viewed as a Foldable:
all :: Foldable t => (a -> Bool) -> t a -> Bool all p (Just x) = p x all p Nothing = True
From a category theory perspective, Option[T] is a sum type representing optional values. OptionForAll implements a natural transformation from predicates on T to predicates on Option[T], preserving the logical structure where:
- The None case represents the "empty" or "absent" case
- The Some case represents the "present" case that must satisfy the predicate
This is dual to Exists, which implements existential quantification:
- OptionForAll: "all elements satisfy p" (true for empty, requires p for non-empty)
- Exists: "some element satisfies p" (false for empty, requires p for non-empty)
The relationship follows De Morgan's laws:
- OptionForAll(p) ≡ not(Exists(not(p)))
- Exists(p) ≡ not(OptionForAll(not(p)))
Type Parameters:
- T: The type of the value contained in the Option
Parameters:
- p: A predicate function that tests values of type T
Returns:
A Predicate function that takes an Option[T] and returns true if it's None or Some with p satisfied
Example:
import (
O "github.com/IBM/fp-go/v2/option"
N "github.com/IBM/fp-go/v2/number"
)
// Check if Option is None or contains a positive number
isPositive := N.MoreThan(0)
allPositive := O.OptionForAll(isPositive)
result1 := allPositive(O.Some(5))
// result1 = true (Some with positive value satisfies predicate)
result2 := allPositive(O.Some(-3))
// result2 = false (Some with non-positive value fails predicate)
result3 := allPositive(O.None[int]())
// result3 = true (None is vacuously true - no value to check)
// Use in validation: ensure all present values meet criteria
values := []O.Option[int]{
O.Some(5),
O.None[int](), // Ignored (vacuously true)
O.Some(10),
O.Some(-3), // Fails validation
}
allValid := true
for _, v := range values {
if !allPositive(v) {
allValid = false
break
}
}
// allValid would be false because Some(-3) fails the predicate
// Contrast with Exists:
hasPositive := O.Exists(isPositive)
// hasPositive checks if there EXISTS a Some value satisfying p
// allPositive checks if ALL Some values satisfy p (None is ignored)
See Also:
- Exists: Tests if Option is Some and satisfies a predicate (existential quantification)
- Filter: Converts Some values that fail a predicate to None
- IsSome: Tests if Option is Some without checking the value
type Prism ¶
type Prism[S, A any] struct { // GetOption attempts to extract a value of type A from S. // Returns Some(a) if the extraction succeeds, None otherwise. GetOption OptionKleisli[S, A] // ReverseGet constructs an S from an A. // This operation always succeeds. ReverseGet func(A) S // contains filtered or unexported fields }
Prism is an optic used to select part of a sum type (tagged union). It provides two operations:
- GetOption: Try to extract a value of type A from S (may fail)
- ReverseGet: Construct an S from an A (always succeeds)
Prisms are useful for working with variant types like Either, Option, or custom sum types where you want to focus on a specific variant.
Type Parameters:
- S: The source type (sum type)
- A: The focus type (variant within the sum type)
Example:
type Result interface{ isResult() }
type Success struct{ Value int }
type Failure struct{ Error string }
successPrism := MakePrism(
func(r Result) Option[int] {
if s, ok := r.(Success); ok {
return Some(s.Value)
}
return None[int]()
},
func(v int) Result { return Success{Value: v} },
)
func MakePrism ¶
func MakePrism[S, A any](get OptionKleisli[S, A], rev func(A) S) Prism[S, A]
MakePrism constructs a Prism from GetOption and ReverseGet functions.
Parameters:
- get: Function to extract A from S (returns Option[A])
- rev: Function to construct S from A
Returns:
- A Prism[S, A] that uses the provided functions
Example:
prism := MakePrism(
func(opt Option[int]) Option[int] { return opt },
func(n int) Option[int] { return Some(n) },
)
func MakePrismWithName ¶
func MakePrismWithName[S, A any](get OptionKleisli[S, A], rev func(A) S, name string) Prism[S, A]
func PrismFromOption ¶
PrismFromOption creates a prism for extracting values from Option types. It provides a safe way to work with Option values, focusing on the Some case and handling the None case gracefully through the prism's GetOption behavior.
The prism's GetOption is the identity function - it returns the Option as-is. If the Option is Some(value), GetOption returns Some(value); if it's None, it returns None. This allows the prism to naturally handle the presence or absence of a value.
The prism's ReverseGet wraps a value into Some, always succeeding.
Type Parameters:
- T: The value type contained in the Option
Returns:
- A Prism[Option[T], T] that safely extracts values from Options
Example:
// Create a prism for extracting int values from Option[int]
optPrism := FromOption[int]()
// Extract from Some
someValue := option.Some(42)
result := optPrism.GetOption(someValue) // Some(42)
// Extract from None
noneValue := option.None[int]()
result = optPrism.GetOption(noneValue) // None[int]()
// Wrap value into Some
wrapped := optPrism.ReverseGet(100) // Some(100)
// Use with Set to update Some values
setter := Set[Option[int], int](200)
result := setter(optPrism)(someValue) // Some(200)
result = setter(optPrism)(noneValue) // None[int]() (unchanged)
// Compose with other prisms for nested extraction
// Extract int from Option[Option[int]]
nestedPrism := Compose[Option[Option[int]], Option[int], int](
FromOption[Option[int]](),
FromOption[int](),
)
nested := option.Some(option.Some(42))
value := nestedPrism.GetOption(nested) // Some(42)
Common use cases:
- Extracting values from optional fields
- Working with nullable data in a type-safe way
- Composing with other prisms to handle nested Options
- Filtering and transforming optional values in pipelines
- Converting between Option and other optional representations
Key insight: This prism treats Option[T] as a "container" that may or may not hold a value of type T. The prism focuses on the value inside, allowing you to work with it when present and gracefully handle its absence when not.
func PrismFromPredicate ¶
PrismFromPredicate creates a prism that matches values satisfying a predicate. GetOption returns Some(s) if the predicate is true, None otherwise. ReverseGet is the identity function (doesn't validate the predicate).
Parameters:
- pred: Predicate function to test values
Returns:
- A Prism[S, S] that filters based on the predicate
Example:
positivePrism := PrismFromPredicate(N.MoreThan(0)) value := positivePrism.GetOption(42) // Some(42) value = positivePrism.GetOption(-5) // None[int]
func PrismId ¶
PrismId returns an identity prism that focuses on the entire value. GetOption always returns Some(s), and ReverseGet is the identity function.
This is useful as a starting point for prism composition or when you need a prism that doesn't actually transform the value.
Example:
idPrism := PrismId[int]() value := idPrism.GetOption(42) // Some(42) result := idPrism.ReverseGet(42) // 42
func PrismSome ¶
PrismSome creates a prism that focuses on the PrismSome variant of an Option within a structure. It composes the provided prism (which focuses on an Option[A]) with a prism that extracts the value from PrismSome.
Type Parameters:
- S: The source type
- A: The value type within the Option
Parameters:
- soa: A prism that focuses on an Option[A] within S
Returns:
- A prism that focuses on the A value within PrismSome
Example:
type Config struct { Timeout Option[int] }
configPrism := MakePrism(...) // Prism[Config, Option[int]]
timeoutPrism := PrismSome(configPrism) // Prism[Config, int]
value := timeoutPrism.GetOption(Config{Timeout: PrismSome(30)}) // PrismSome(30)
func (Prism[S, A]) Compose ¶
Compose returns a new prism that focuses deeper into a sum type by chaining this prism (S → A) with an inner prism (A → B), producing a composed prism (S → B).
This is the method-receiver form of the package-level OptionalComposeOptional function, available only on Go 1.27 and later because Go did not support type parameters on methods before that version. On earlier toolchains, use the equivalent free function instead:
// method form (go1.27+) composed := outerPrism.Compose(innerPrism) // free-function form (all versions) composed := prism.Compose[S](innerPrism)(outerPrism)
GetOption of the composed prism chains the two GetOption functions: it first applies the outer prism to obtain an Option[A], then chains the inner prism through that option via O.Chain, returning None whenever either prism fails to match.
ReverseGet of the composed prism pipes the value back through both ReverseGet functions in order: inner first, then outer.
The composed prism satisfies both prism laws whenever both constituent prisms individually satisfy them.
Type Parameters:
- B: the focus type of the inner prism and of the resulting prism
Parameters:
- ab: the inner prism from A to B
Returns:
- Prism[S, B]: a new prism from S directly to B
See Also:
- Compose: the equivalent package-level function
func (Prism) Format ¶
Format implements fmt.Formatter.
Supports all standard format verbs:
- %s, %v, %+v, %q, and all other verbs: uses the String() representation (the prism name)
The exact output format is not a stable contract and may change across versions.
type PrismKleisli ¶
Kleisli represents a function that takes a value of type A and returns a Prism[S, B]. This is commonly used for composing prisms in a monadic style.
Type Parameters:
- S: The source type of the resulting prism
- A: The input type to the function
- B: The focus type of the resulting prism
type PrismOperator ¶
Operator represents a function that transforms one prism into another. It takes a Prism[S, A] and returns a Prism[S, B], allowing for prism transformations.
Type Parameters:
- S: The source type (remains constant)
- A: The original focus type
- B: The new focus type
func PrismComposePrism ¶
Compose composes two prisms to create a prism that focuses deeper into a structure. The resulting prism first applies the outer prism (S → A), then the inner prism (A → B).
Type Parameters:
- S: The outermost source type
- A: The intermediate type
- B: The innermost focus type
Parameters:
- ab: The inner prism (A → B)
Returns:
- A function that takes the outer prism (S → A) and returns the composed prism (S → B)
Example:
outerPrism := MakePrism(...) // Prism[Outer, Inner] innerPrism := MakePrism(...) // Prism[Inner, Value] composed := Compose[Outer](innerPrism)(outerPrism) // Prism[Outer, Value]
func PrismIMap ¶
PrismIMap bidirectionally maps the focus type of a prism. It transforms a Prism[S, A] into a Prism[S, B] using two functions: one to map A → B and another to map B → A.
Type Parameters:
- S: The source type
- A: The original focus type
- B: The new focus type
- AB: Function type A → B
- BA: Function type B → A
Parameters:
- ab: Function to map from A to B
- ba: Function to map from B to A
Returns:
- A function that transforms Prism[S, A] to Prism[S, B]
Example:
intPrism := MakePrism(...) // Prism[Result, int]
stringPrism := PrismIMap[Result](
strconv.Itoa,
func(s string) int { n, _ := strconv.Atoi(s); return n },
)(intPrism) // Prism[Result, string]