Documentation
¶
Overview ¶
Package iso provides utilities for composing isomorphisms with prisms.
This package enables the composition of isomorphisms (bidirectional transformations) with prisms (optics for sum types), allowing you to transform the focus type of a prism using an isomorphism. This is particularly useful when you need to work with prisms that focus on a type that can be bidirectionally converted to another type.
Key Concepts ¶
An Iso[S, A] represents a bidirectional transformation between types S and A without loss of information. A Prism[S, A] is an optic that focuses on a specific variant within a sum type S, extracting values of type A.
When you compose an Iso[A, B] with a Prism[S, A], you get a Prism[S, B] that:
- Extracts values of type A from S (using the prism)
- Transforms them to type B (using the isomorphism's Get)
- Can construct S from B by reversing the transformation (using the isomorphism's ReverseGet)
Example Usage ¶
import (
"github.com/IBM/fp-go/v2/optics/iso"
"github.com/IBM/fp-go/v2/optics/prism"
PI "github.com/IBM/fp-go/v2/optics/prism/iso"
O "github.com/IBM/fp-go/v2/option"
)
// Create an isomorphism between string and []byte
stringBytesIso := iso.MakeIso(
func(s string) []byte { return []byte(s) },
func(b []byte) string { return string(b) },
)
// Create a prism that extracts Right values from Either[error, string]
rightPrism := prism.FromEither[error, string]()
// Compose them to get a prism that extracts Right values as []byte
bytesPrism := PI.Compose(stringBytesIso)(rightPrism)
// Use the composed prism
either := either.Right[error]("hello")
result := bytesPrism.GetOption(either) // Some([]byte("hello"))
Type Aliases ¶
This package re-exports key types from the iso and prism packages for convenience:
- Iso[S, A]: An isomorphism between types S and A
- Prism[S, A]: A prism focusing on type A within sum type S
- Operator[S, A, B]: A function that transforms Prism[S, A] to Prism[S, B]
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Iso ¶
Iso represents an isomorphism between types S and A. It is a bidirectional transformation that converts between two types without any loss of information.
Type Parameters:
- S: The source type
- A: The target type
See github.com/IBM/fp-go/v2/optics/iso for the full Iso API.
type Operator ¶
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.
This is commonly used with the Compose function to create operators that transform the focus type of a prism using an isomorphism.
Type Parameters:
- S: The source type (remains constant)
- A: The original focus type
- B: The new focus type
Example:
// Create an operator that transforms string prisms to []byte prisms stringToBytesOp := Compose(stringBytesIso) // Apply it to a prism bytesPrism := stringToBytesOp(stringPrism)
func Compose ¶
Compose creates an operator that composes an isomorphism with a prism.
This function takes an isomorphism Iso[A, B] and returns an operator that can transform any Prism[S, A] into a Prism[S, B]. The resulting prism maintains the same source type S but changes the focus type from A to B using the bidirectional transformation provided by the isomorphism.
The composition works as follows:
- GetOption: First extracts A from S using the prism, then transforms A to B using the iso's Get
- ReverseGet: First transforms B to A using the iso's ReverseGet, then constructs S using the prism's ReverseGet
This is particularly useful when you have a prism that focuses on one type but you need to work with a different type that has a lossless bidirectional transformation to the original type.
Haskell Equivalent: This corresponds to the (.) operator for composing optics in Haskell's lens library, specifically when composing a Prism with an Iso:
prism . iso :: Prism s a -> Iso a b -> Prism s b
In Haskell's lens library, this is part of the general optic composition mechanism. See: https://hackage.haskell.org/package/lens/docs/Control-Lens-Prism.html
Type Parameters:
- S: The source type (sum type) that the prism operates on
- A: The original focus type of the prism
- B: The new focus type after applying the isomorphism
Parameters:
- ab: An isomorphism between types A and B that defines the bidirectional transformation
Returns:
- An Operator[S, A, B] that transforms Prism[S, A] into Prism[S, B]
Laws: The composed prism must satisfy the prism laws:
- GetOption(ReverseGet(b)) == Some(b) for all b: B
- If GetOption(s) == Some(a), then GetOption(ReverseGet(a)) == Some(a)
These laws are preserved because:
- The isomorphism satisfies: ab.ReverseGet(ab.Get(a)) == a and ab.Get(ab.ReverseGet(b)) == b
- The original prism satisfies the prism laws
Example - Composing string/bytes isomorphism with Either prism:
import (
"github.com/IBM/fp-go/v2/either"
"github.com/IBM/fp-go/v2/optics/iso"
"github.com/IBM/fp-go/v2/optics/prism"
PI "github.com/IBM/fp-go/v2/optics/prism/iso"
O "github.com/IBM/fp-go/v2/option"
)
// Create an isomorphism between string and []byte
stringBytesIso := iso.MakeIso(
func(s string) []byte { return []byte(s) },
func(b []byte) string { return string(b) },
)
// Create a prism that extracts Right values from Either[error, string]
rightPrism := prism.FromEither[error, string]()
// Compose them to get a prism that works with []byte instead of string
bytesPrism := PI.Compose(stringBytesIso)(rightPrism)
// Extract bytes from a Right value
success := either.Right[error]("hello")
result := bytesPrism.GetOption(success)
// result is Some([]byte("hello"))
// Extract from a Left value returns None
failure := either.Left[string](errors.New("error"))
result = bytesPrism.GetOption(failure)
// result is None
// Construct an Either from bytes
constructed := bytesPrism.ReverseGet([]byte("world"))
// constructed is Right("world")
Example - Composing with custom types:
type Celsius float64
type Fahrenheit float64
// Isomorphism between Celsius and Fahrenheit
tempIso := iso.MakeIso(
func(c Celsius) Fahrenheit { return Fahrenheit(c*9/5 + 32) },
func(f Fahrenheit) Celsius { return Celsius((f - 32) * 5 / 9) },
)
// Prism that extracts temperature from a weather report
type WeatherReport struct {
Temperature Celsius
Condition string
}
tempPrism := prism.MakePrism(
func(w WeatherReport) option.Option[Celsius] {
return option.Some(w.Temperature)
},
func(c Celsius) WeatherReport {
return WeatherReport{Temperature: c}
},
)
// Compose to work with Fahrenheit instead
fahrenheitPrism := PI.Compose(tempIso)(tempPrism)
report := WeatherReport{Temperature: 20, Condition: "sunny"}
temp := fahrenheitPrism.GetOption(report)
// temp is Some(68.0) in Fahrenheit
See also:
- github.com/IBM/fp-go/v2/optics/iso for isomorphism operations
- github.com/IBM/fp-go/v2/optics/prism for prism operations
- Operator for the type signature of the returned function
type Prism ¶
Prism is an optic used to select part of a sum type (tagged union). It provides operations to extract and construct values within sum types.
Type Parameters:
- S: The source type (sum type)
- A: The focus type (variant within the sum type)
See github.com/IBM/fp-go/v2/optics/prism for the full Prism API.