iso

package
v2.2.21 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 24, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

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

type Iso[S, A any] = I.Iso[S, A]

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

type Operator[S, A, B any] = P.Operator[S, A, B]

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

func Compose[S, A, B any](ab Iso[A, B]) Operator[S, A, B]

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:

  1. GetOption(ReverseGet(b)) == Some(b) for all b: B
  2. 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

type Prism[S, A any] = P.Prism[S, A]

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL