lens

package
v2.1.13 Latest Latest
Warning

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

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

README

Lens Generator Example

This example demonstrates the lens code generator for Go structs.

Overview

The lens generator automatically creates lens types for Go structs annotated with fp-go:Lens. Lenses provide a functional way to access and update nested immutable data structures.

Usage

1. Annotate Your Structs

Add the fp-go:Lens annotation in a comment above your struct declaration:

// fp-go:Lens
type Person struct {
    Name  string
    Age   int
    Email string
    Phone *string  // Pointer fields generate LensO (optional lens)
}
2. Generate Lens Code

Run the generator command:

go run ../../main.go lens --dir . --filename gen.go

Or use it as a go generate directive:

//go:generate go run ../../main.go lens --dir . --filename gen.go
3. Use the Generated Lenses

The generator creates:

  • A <TypeName>Lens struct with a lens for each exported field
  • A Make<TypeName>Lens() constructor function
// Create lenses
lenses := MakePersonLens()

// Get a field value
name := lenses.Name.Get(person)

// Set a field value (returns a new instance)
updated := lenses.Name.Set("Bob")(person)

// Modify a field value
incremented := F.Pipe1(
    lenses.Age,
    L.Modify[Person](func(age int) int { return age + 1 }),
)(person)

Features

Optional Fields (LensO)

Pointer fields automatically generate LensO (optional lenses) that work with Option[*T]:

// fp-go:Lens
type Person struct {
    Name  string
    Phone *string  // Generates LensO[Person, *string]
}

lenses := MakePersonLens()
person := Person{Name: "Alice", Phone: nil}

// Get returns Option[*string]
phoneOpt := lenses.Phone.Get(person)  // None

// Set with Some
phone := "555-1234"
updated := lenses.Phone.Set(O.Some(&phone))(person)

// Set with None (clears the field)
cleared := lenses.Phone.Set(O.None[*string]())(person)
Immutable Updates

All lens operations return new instances, leaving the original unchanged:

person := Person{Name: "Alice", Age: 30}
updated := lenses.Name.Set("Bob")(person)
// person.Name is still "Alice"
// updated.Name is "Bob"
Lens Composition

Compose lenses to access deeply nested fields:

// Access company.CEO.Name
ceoNameLens := F.Pipe1(
    companyLenses.CEO,
    L.Compose[Company](personLenses.Name),
)

name := ceoNameLens.Get(company)
updated := ceoNameLens.Set("Jane")(company)
Type Safety

All operations are type-safe at compile time:

// Compile error: type mismatch
lenses.Age.Set("not a number")(person)

Generated Code Structure

For each annotated struct, the generator creates:

// Lens struct with a lens for each field
type PersonLens struct {
    Name  L.Lens[Person, string]
    Age   L.Lens[Person, int]
    Email L.Lens[Person, string]
}

// Constructor function
func MakePersonLens() PersonLens {
    return PersonLens{
        Name: L.MakeLens(
            func(s Person) string { return s.Name },
            func(s Person, v string) Person { s.Name = v; return s },
        ),
        // ... other fields
    }
}

Generated Code Structure

For each annotated struct, the generator creates:

// Regular field generates Lens
type PersonLens struct {
    Name  L.Lens[Person, string]
    Phone LO.LensO[Person, *string]  // Pointer field generates LensO
}

// Constructor function
func MakePersonLens() PersonLens {
    return PersonLens{
        Name: L.MakeLens(
            func(s Person) string { return s.Name },
            func(s Person, v string) Person { s.Name = v; return s },
        ),
        Phone: L.MakeLens(
            func(s Person) O.Option[*string] { return O.FromNillable(s.Phone) },
            func(s Person, v O.Option[*string]) Person {
                s.Phone = O.GetOrElse(func() *string { return nil })(v)
                return s
            },
        ),
    }
}

Command Options

  • --dir: Directory to scan for Go files (default: ".")
  • --filename: Name of the generated file (default: "gen.go")

Notes

  • Only pointer fields (*T) generate LensO (optional lenses)
  • The json:"...,omitempty" tag alone does not make a field optional in the lens generator
  • Pointer fields work with Option[*T] using FromNillable and GetOrElse

Examples

See example_test.go for comprehensive examples including:

  • Basic lens operations (Get, Set, Modify)
  • Nested struct access
  • Lens composition
  • Complex data structure manipulation

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Address

type Address struct {
	Street  string
	City    string
	ZipCode string
	Country string
	// Optional field
	State *string `json:"state,omitempty"`
}

fp-go:Lens

type AddressLenses

type AddressLenses struct {
	// mandatory fields
	Street  __lens.Lens[Address, string]
	City    __lens.Lens[Address, string]
	ZipCode __lens.Lens[Address, string]
	Country __lens.Lens[Address, string]
	State   __lens.Lens[Address, *string]
	// optional fields
	StreetO  __lens_option.LensO[Address, string]
	CityO    __lens_option.LensO[Address, string]
	ZipCodeO __lens_option.LensO[Address, string]
	CountryO __lens_option.LensO[Address, string]
	StateO   __lens_option.LensO[Address, *string]
}

AddressLenses provides lenses for accessing fields of Address

func MakeAddressLenses

func MakeAddressLenses() AddressLenses

MakeAddressLenses creates a new AddressLenses with lenses for all fields

type AddressPrisms

type AddressPrisms struct {
	Street  __prism.Prism[Address, string]
	City    __prism.Prism[Address, string]
	ZipCode __prism.Prism[Address, string]
	Country __prism.Prism[Address, string]
	State   __prism.Prism[Address, *string]
}

AddressPrisms provides prisms for accessing fields of Address

func MakeAddressPrisms

func MakeAddressPrisms() AddressPrisms

MakeAddressPrisms creates a new AddressPrisms with prisms for all fields

type AddressRefLenses

type AddressRefLenses struct {
	// mandatory fields
	Street  __lens.Lens[*Address, string]
	City    __lens.Lens[*Address, string]
	ZipCode __lens.Lens[*Address, string]
	Country __lens.Lens[*Address, string]
	State   __lens.Lens[*Address, *string]
	// optional fields
	StreetO  __lens_option.LensO[*Address, string]
	CityO    __lens_option.LensO[*Address, string]
	ZipCodeO __lens_option.LensO[*Address, string]
	CountryO __lens_option.LensO[*Address, string]
	StateO   __lens_option.LensO[*Address, *string]
	// prisms
	StreetP  __prism.Prism[*Address, string]
	CityP    __prism.Prism[*Address, string]
	ZipCodeP __prism.Prism[*Address, string]
	CountryP __prism.Prism[*Address, string]
	StateP   __prism.Prism[*Address, *string]
}

AddressRefLenses provides lenses for accessing fields of Address via a reference to Address

func MakeAddressRefLenses

func MakeAddressRefLenses() AddressRefLenses

MakeAddressRefLenses creates a new AddressRefLenses with lenses for all fields

type CheckOption

type CheckOption struct {
	Name  option.Option[string]
	Value string `json:",omitempty"`
}

fp-go:Lens

type CheckOptionLenses

type CheckOptionLenses struct {
	// mandatory fields
	Name  __lens.Lens[CheckOption, option.Option[string]]
	Value __lens.Lens[CheckOption, string]
	// optional fields
	ValueO __lens_option.LensO[CheckOption, string]
}

CheckOptionLenses provides lenses for accessing fields of CheckOption

func MakeCheckOptionLenses

func MakeCheckOptionLenses() CheckOptionLenses

MakeCheckOptionLenses creates a new CheckOptionLenses with lenses for all fields

type CheckOptionPrisms

type CheckOptionPrisms struct {
	Name  __prism.Prism[CheckOption, option.Option[string]]
	Value __prism.Prism[CheckOption, string]
}

CheckOptionPrisms provides prisms for accessing fields of CheckOption

func MakeCheckOptionPrisms

func MakeCheckOptionPrisms() CheckOptionPrisms

MakeCheckOptionPrisms creates a new CheckOptionPrisms with prisms for all fields

type CheckOptionRefLenses

type CheckOptionRefLenses struct {
	// mandatory fields
	Name  __lens.Lens[*CheckOption, option.Option[string]]
	Value __lens.Lens[*CheckOption, string]
	// optional fields
	ValueO __lens_option.LensO[*CheckOption, string]
	// prisms
	NameP  __prism.Prism[*CheckOption, option.Option[string]]
	ValueP __prism.Prism[*CheckOption, string]
}

CheckOptionRefLenses provides lenses for accessing fields of CheckOption via a reference to CheckOption

func MakeCheckOptionRefLenses

func MakeCheckOptionRefLenses() CheckOptionRefLenses

MakeCheckOptionRefLenses creates a new CheckOptionRefLenses with lenses for all fields

type Company

type Company struct {
	Name    string
	Address Address
	CEO     Person
	// Optional field
	Website *string
}

fp-go:Lens

type CompanyExtended

type CompanyExtended struct {
	Company
	Extended string
}

fp-go:Lens

type CompanyExtendedLenses

CompanyExtendedLenses provides lenses for accessing fields of CompanyExtended

func MakeCompanyExtendedLenses

func MakeCompanyExtendedLenses() CompanyExtendedLenses

MakeCompanyExtendedLenses creates a new CompanyExtendedLenses with lenses for all fields

type CompanyExtendedPrisms

CompanyExtendedPrisms provides prisms for accessing fields of CompanyExtended

func MakeCompanyExtendedPrisms

func MakeCompanyExtendedPrisms() CompanyExtendedPrisms

MakeCompanyExtendedPrisms creates a new CompanyExtendedPrisms with prisms for all fields

type CompanyExtendedRefLenses

CompanyExtendedRefLenses provides lenses for accessing fields of CompanyExtended via a reference to CompanyExtended

func MakeCompanyExtendedRefLenses

func MakeCompanyExtendedRefLenses() CompanyExtendedRefLenses

MakeCompanyExtendedRefLenses creates a new CompanyExtendedRefLenses with lenses for all fields

type CompanyLenses

type CompanyLenses struct {
	// mandatory fields
	Name    __lens.Lens[Company, string]
	Address __lens.Lens[Company, Address]
	CEO     __lens.Lens[Company, Person]
	Website __lens.Lens[Company, *string]
	// optional fields
	NameO    __lens_option.LensO[Company, string]
	AddressO __lens_option.LensO[Company, Address]
	CEOO     __lens_option.LensO[Company, Person]
	WebsiteO __lens_option.LensO[Company, *string]
}

CompanyLenses provides lenses for accessing fields of Company

func MakeCompanyLenses

func MakeCompanyLenses() CompanyLenses

MakeCompanyLenses creates a new CompanyLenses with lenses for all fields

type CompanyPrisms

type CompanyPrisms struct {
	Name    __prism.Prism[Company, string]
	Address __prism.Prism[Company, Address]
	CEO     __prism.Prism[Company, Person]
	Website __prism.Prism[Company, *string]
}

CompanyPrisms provides prisms for accessing fields of Company

func MakeCompanyPrisms

func MakeCompanyPrisms() CompanyPrisms

MakeCompanyPrisms creates a new CompanyPrisms with prisms for all fields

type CompanyRefLenses

type CompanyRefLenses struct {
	// mandatory fields
	Name    __lens.Lens[*Company, string]
	Address __lens.Lens[*Company, Address]
	CEO     __lens.Lens[*Company, Person]
	Website __lens.Lens[*Company, *string]
	// optional fields
	NameO    __lens_option.LensO[*Company, string]
	AddressO __lens_option.LensO[*Company, Address]
	CEOO     __lens_option.LensO[*Company, Person]
	WebsiteO __lens_option.LensO[*Company, *string]
	// prisms
	NameP    __prism.Prism[*Company, string]
	AddressP __prism.Prism[*Company, Address]
	CEOP     __prism.Prism[*Company, Person]
	WebsiteP __prism.Prism[*Company, *string]
}

CompanyRefLenses provides lenses for accessing fields of Company via a reference to Company

func MakeCompanyRefLenses

func MakeCompanyRefLenses() CompanyRefLenses

MakeCompanyRefLenses creates a new CompanyRefLenses with lenses for all fields

type Person

type Person struct {
	Name  string
	Age   int
	Email string
	// Optional field with pointer
	Phone *string
}

fp-go:Lens

type PersonLenses

type PersonLenses struct {
	// mandatory fields
	Name  __lens.Lens[Person, string]
	Age   __lens.Lens[Person, int]
	Email __lens.Lens[Person, string]
	Phone __lens.Lens[Person, *string]
	// optional fields
	NameO  __lens_option.LensO[Person, string]
	AgeO   __lens_option.LensO[Person, int]
	EmailO __lens_option.LensO[Person, string]
	PhoneO __lens_option.LensO[Person, *string]
}

PersonLenses provides lenses for accessing fields of Person

func MakePersonLenses

func MakePersonLenses() PersonLenses

MakePersonLenses creates a new PersonLenses with lenses for all fields

type PersonPrisms

type PersonPrisms struct {
	Name  __prism.Prism[Person, string]
	Age   __prism.Prism[Person, int]
	Email __prism.Prism[Person, string]
	Phone __prism.Prism[Person, *string]
}

PersonPrisms provides prisms for accessing fields of Person

func MakePersonPrisms

func MakePersonPrisms() PersonPrisms

MakePersonPrisms creates a new PersonPrisms with prisms for all fields

type PersonRefLenses

type PersonRefLenses struct {
	// mandatory fields
	Name  __lens.Lens[*Person, string]
	Age   __lens.Lens[*Person, int]
	Email __lens.Lens[*Person, string]
	Phone __lens.Lens[*Person, *string]
	// optional fields
	NameO  __lens_option.LensO[*Person, string]
	AgeO   __lens_option.LensO[*Person, int]
	EmailO __lens_option.LensO[*Person, string]
	PhoneO __lens_option.LensO[*Person, *string]
	// prisms
	NameP  __prism.Prism[*Person, string]
	AgeP   __prism.Prism[*Person, int]
	EmailP __prism.Prism[*Person, string]
	PhoneP __prism.Prism[*Person, *string]
}

PersonRefLenses provides lenses for accessing fields of Person via a reference to Person

func MakePersonRefLenses

func MakePersonRefLenses() PersonRefLenses

MakePersonRefLenses creates a new PersonRefLenses with lenses for all fields

type WithGeneric

type WithGeneric[T any] struct {
	Name  string
	Value T
}

fp-go:Lens

type WithGenericLenses

type WithGenericLenses[T any] struct {
	// mandatory fields
	Name  __lens.Lens[WithGeneric[T], string]
	Value __lens.Lens[WithGeneric[T], T]
	// optional fields
	NameO __lens_option.LensO[WithGeneric[T], string]
}

WithGenericLenses provides lenses for accessing fields of WithGeneric

func MakeWithGenericLenses

func MakeWithGenericLenses[T any]() WithGenericLenses[T]

MakeWithGenericLenses creates a new WithGenericLenses with lenses for all fields

type WithGenericPrisms

type WithGenericPrisms[T any] struct {
	Name  __prism.Prism[WithGeneric[T], string]
	Value __prism.Prism[WithGeneric[T], T]
}

WithGenericPrisms provides prisms for accessing fields of WithGeneric

func MakeWithGenericPrisms

func MakeWithGenericPrisms[T any]() WithGenericPrisms[T]

MakeWithGenericPrisms creates a new WithGenericPrisms with prisms for all fields

type WithGenericRefLenses

type WithGenericRefLenses[T any] struct {
	// mandatory fields
	Name  __lens.Lens[*WithGeneric[T], string]
	Value __lens.Lens[*WithGeneric[T], T]
	// optional fields
	NameO __lens_option.LensO[*WithGeneric[T], string]
	// prisms
	NameP  __prism.Prism[*WithGeneric[T], string]
	ValueP __prism.Prism[*WithGeneric[T], T]
}

WithGenericRefLenses provides lenses for accessing fields of WithGeneric via a reference to WithGeneric

func MakeWithGenericRefLenses

func MakeWithGenericRefLenses[T any]() WithGenericRefLenses[T]

MakeWithGenericRefLenses creates a new WithGenericRefLenses with lenses for all fields

Jump to

Keyboard shortcuts

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