Documentation
¶
Overview ¶
Package prism provides utilities for composing prisms with isomorphisms.
This package enables the composition of prisms (optics for sum types) with isomorphisms (bidirectional transformations), allowing you to transform the source type of a prism using an isomorphism. This is the inverse operation of optics/prism/iso, where we transform the focus type instead of the source type.
Key Concepts ¶
A Prism[S, A] is an optic that focuses on a specific variant within a sum type S, extracting values of type A. An Iso[S, A] represents a bidirectional transformation between types S and A without loss of information.
When you compose a Prism[A, B] with an Iso[S, A], you get a Prism[S, B] that:
- Transforms S to A using the isomorphism's Get
- Extracts values of type B from A (using the prism)
- Can construct S from B by first using the prism's ReverseGet to get A, then the iso's ReverseGet
Example Usage ¶
import (
"github.com/IBM/fp-go/v2/optics/iso"
"github.com/IBM/fp-go/v2/optics/prism"
IP "github.com/IBM/fp-go/v2/optics/iso/prism"
O "github.com/IBM/fp-go/v2/option"
)
// Create an isomorphism between []byte and string
bytesStringIso := iso.MakeIso(
func(b []byte) string { return string(b) },
func(s string) []byte { return []byte(s) },
)
// 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 as source
bytesPrism := IP.Compose(rightPrism)(bytesStringIso)
// Use the composed prism
bytes := []byte(`{"status":"ok"}`)
// First converts bytes to string via iso, then extracts Right value
result := bytesPrism.GetOption(either.Right[error](string(bytes)))
Comparison with optics/prism/iso ¶
This package (optics/iso/prism) is the dual of optics/prism/iso:
- optics/prism/iso: Composes Iso[A, B] with Prism[S, A] → Prism[S, B] (transforms focus type)
- optics/iso/prism: Composes Prism[A, B] with Iso[S, A] → Prism[S, B] (transforms source type)
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
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Compose ¶
Compose creates a Kleisli arrow that composes a prism with an isomorphism.
This function takes a Prism[A, B] and returns a Kleisli arrow that can transform any Iso[S, A] into a Prism[S, B]. The resulting prism changes the source type from A to S using the bidirectional transformation provided by the isomorphism, while maintaining the same focus type B.
The composition works as follows:
- GetOption: First transforms S to A using the iso's Get, then extracts B from A using the prism's GetOption
- ReverseGet: First constructs A from B using the prism's ReverseGet, then transforms A to S using the iso's ReverseGet
This is the dual operation of optics/prism/iso.Compose:
- optics/prism/iso.Compose: Transforms the focus type (A → B) while keeping source type (S) constant
- optics/iso/prism.Compose: Transforms the source type (A → S) while keeping focus type (B) constant
This is particularly useful when you have a prism that works with one type but you need to adapt it to work with a different source type that has a lossless bidirectional transformation to the original type.
Type Parameters:
- S: The new source type after applying the isomorphism
- A: The original source type of the prism
- B: The focus type (remains constant through composition)
Parameters:
- ab: A prism that extracts B from A
Returns:
- A Kleisli arrow (function) that takes an Iso[S, A] and returns a 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: ia.ReverseGet(ia.Get(s)) == s and ia.Get(ia.ReverseGet(a)) == a
- The original prism satisfies the prism laws
Haskell Equivalent: This corresponds to the (.) operator for composing optics in Haskell's lens library, specifically when composing an Iso with a Prism:
iso . prism :: Iso s a -> Prism 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-Iso.html
Example - Composing 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"
IP "github.com/IBM/fp-go/v2/optics/iso/prism"
O "github.com/IBM/fp-go/v2/option"
)
// Create a prism that extracts Right values from Either[error, string]
rightPrism := prism.FromEither[error, string]()
// Create an isomorphism between []byte and string
bytesStringIso := iso.MakeIso(
func(b []byte) string { return string(b) },
func(s string) []byte { return []byte(s) },
)
// Compose them to get a prism that works with []byte as source
bytesPrism := IP.Compose(rightPrism)(bytesStringIso)
// Use the composed prism
// First converts []byte to string via iso, then extracts Right value
bytes := []byte("hello")
either := either.Right[error](string(bytes))
result := bytesPrism.GetOption(bytes) // Extracts "hello" if Right
// Construct []byte from string
constructed := bytesPrism.ReverseGet("world")
// Returns []byte("world") wrapped in Right
Example - Composing with custom types:
type JSON []byte
type Config struct {
Host string
Port int
}
// Isomorphism between JSON and []byte
jsonIso := iso.MakeIso(
func(j JSON) []byte { return []byte(j) },
func(b []byte) JSON { return JSON(b) },
)
// Prism that extracts Config from []byte (via JSON parsing)
configPrism := prism.MakePrism(
func(b []byte) option.Option[Config] {
var cfg Config
if err := json.Unmarshal(b, &cfg); err != nil {
return option.None[Config]()
}
return option.Some(cfg)
},
func(cfg Config) []byte {
b, _ := json.Marshal(cfg)
return b
},
)
// Compose to work with JSON type instead of []byte
jsonConfigPrism := IP.Compose(configPrism)(jsonIso)
jsonData := JSON(`{"host":"localhost","port":8080}`)
config := jsonConfigPrism.GetOption(jsonData)
// config is Some(Config{Host: "localhost", Port: 8080})
See also:
- github.com/IBM/fp-go/v2/optics/iso for isomorphism operations
- github.com/IBM/fp-go/v2/optics/prism for prism operations
- github.com/IBM/fp-go/v2/optics/prism/iso for the dual composition (transforming focus type)
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 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.