or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/pypi-lenses

A lens library for python that enables immutable manipulation of deeply nested data structures

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/lenses@1.2.x

To install, run

npx @tessl/cli install tessl/pypi-lenses@1.2.0

0

# Lenses

1

2

A comprehensive Python lens library that enables immutable manipulation of deeply nested data structures without mutation. Inspired by Haskell lenses but adapted for Python's syntax and conventions, providing a functional programming approach to data transformation through a chainable API.

3

4

## Package Information

5

6

- **Package Name**: lenses

7

- **Language**: Python

8

- **Installation**: `pip install lenses`

9

- **Optional Dependencies**: `pip install pyrsistent` (for enhanced immutable data structures)

10

11

## Core Imports

12

13

```python

14

from lenses import lens, bind

15

```

16

17

For advanced usage:

18

19

```python

20

from lenses import lens, bind, UnboundLens

21

from lenses.maybe import Just, Nothing

22

```

23

24

## Basic Usage

25

26

```python

27

from lenses import lens, bind

28

29

# Basic lens operations on lists

30

data = [1, 2, 3, 4, 5]

31

32

# Get values

33

first_item = lens[0].get()(data) # 1

34

all_items = lens.Each().collect()(data) # [1, 2, 3, 4, 5]

35

36

# Set values (returns new list)

37

new_data = lens[1].set(99)(data) # [1, 99, 3, 4, 5]

38

39

# Modify values with functions

40

incremented = lens.Each().modify(lambda x: x + 1)(data) # [2, 3, 4, 5, 6]

41

42

# Working with dictionaries

43

person = {'name': 'Alice', 'age': 30, 'address': {'city': 'Boston', 'state': 'MA'}}

44

45

# Access nested data

46

city = lens['address']['city'].get()(person) # 'Boston'

47

48

# Update nested data immutably

49

updated_person = lens['address']['city'].set('Cambridge')(person)

50

# {'name': 'Alice', 'age': 30, 'address': {'city': 'Cambridge', 'state': 'MA'}}

51

52

# Using bound lenses

53

bound_lens = bind(person)

54

age = bound_lens['age'].get() # 30

55

older_person = bound_lens['age'].modify(lambda x: x + 1)

56

```

57

58

## Architecture

59

60

Lenses provides a layered architecture for immutable data manipulation:

61

62

- **UI Layer**: `UnboundLens` and `BoundLens` classes providing the main user interface

63

- **Optics System**: Low-level optics (Lens, Prism, Traversal, Isomorphism, etc.) that handle the actual data access patterns

64

- **Type Classes**: Functional programming utilities (monoid, functor, applicative)

65

- **Hooks System**: Extension points for custom data types and collections

66

- **Maybe Type**: Optional value handling inspired by functional programming

67

68

This design enables composition of complex data access patterns while maintaining immutability and type safety.

69

70

## Capabilities

71

72

### Core Lens Operations

73

74

The fundamental lens interface providing get, set, modify operations and lens composition through the `&` operator.

75

76

```python { .api }

77

class UnboundLens:

78

def get(self) -> StateFunction[S, B]: ...

79

def set(self, newvalue: B) -> StateFunction[S, T]: ...

80

def modify(self, func: Callable[[A], B]) -> StateFunction[S, T]: ...

81

def __and__(self, other) -> UnboundLens: ...

82

83

class BoundLens:

84

def get(self) -> B: ...

85

def set(self, newvalue: B) -> T: ...

86

def modify(self, func: Callable[[A], B]) -> T: ...

87

88

def bind(state: S) -> BoundLens[S, S, S, S]: ...

89

```

90

91

[Core Lens Operations](./core-lenses.md)

92

93

### Lens Constructors

94

95

Comprehensive collection of lens constructors for accessing different data structures and implementing various access patterns including containers, objects, traversals, and transformations.

96

97

```python { .api }

98

def Each(self) -> BaseUiLens: ...

99

def GetItem(self, key: Any) -> BaseUiLens: ...

100

def GetAttr(self, name: str) -> BaseUiLens: ...

101

def Filter(self, predicate: Callable[[A], bool]) -> BaseUiLens: ...

102

def Items(self) -> BaseUiLens: ...

103

def Values(self) -> BaseUiLens: ...

104

def Keys(self) -> BaseUiLens: ...

105

def Json(self) -> BaseUiLens: ...

106

```

107

108

[Lens Constructors](./lens-constructors.md)

109

110

### Optics System

111

112

Low-level optics system providing the mathematical foundation with different optic types (Lens, Prism, Traversal, Isomorphism, etc.) that can be composed to create complex data access patterns.

113

114

```python { .api }

115

class Lens: ...

116

class Prism: ...

117

class Traversal: ...

118

class Isomorphism: ...

119

class Fold: ...

120

class Setter: ...

121

```

122

123

[Optics System](./optics.md)

124

125

### Utility Types

126

127

Supporting types including Maybe monad for optional values, type class system for functional programming patterns, and hooks system for extending support to custom data types.

128

129

```python { .api }

130

class Just:

131

def __init__(self, item: A) -> None: ...

132

def map(self, fn: Callable[[A], B]) -> Just[B]: ...

133

def maybe(self, guard: B) -> Union[A, B]: ...

134

135

class Nothing(Just): ...

136

137

def mempty(monoid: Any) -> Any: ...

138

def mappend(monoid: Any, other: Any) -> Any: ...

139

```

140

141

[Utility Types](./utility-types.md)

142

143

## Global Variables

144

145

```python { .api }

146

lens: UnboundLens # Main lens object, entry point to the library

147

```

148

149

## Types

150

151

```python { .api }

152

from typing import TypeVar, Callable, List, Iterable, Union, Optional, Any

153

154

S = TypeVar("S") # Source type

155

T = TypeVar("T") # Target type

156

A = TypeVar("A") # Focus input type

157

B = TypeVar("B") # Focus output type

158

159

StateFunction[S, T] = Callable[[S], T]

160

```