lens
lens
Lens-based type transformations for datasets.
This module implements a lens system for bidirectional transformations between different sample types. Lenses enable viewing a dataset through different type schemas without duplicating the underlying data.
Key components:
Lens: Bidirectional transformation with getter (S -> V) and optional putter (V, S -> S)LensNetwork: Global singleton registry for lens transformations@lens: Decorator to create and register lens transformations
Lenses support the functional programming concept of composable, well-behaved transformations that satisfy lens laws (GetPut and PutGet).
Examples
>>> @packable
... class FullData:
... name: str
... age: int
... embedding: NDArray
...
>>> @packable
... class NameOnly:
... name: str
...
>>> @lens
... def name_view(full: FullData) -> NameOnly:
... return NameOnly(name=full.name)
...
>>> @name_view.putter
... def name_view_put(view: NameOnly, source: FullData) -> FullData:
... return FullData(name=view.name, age=source.age,
... embedding=source.embedding)
...
>>> ds = Dataset[FullData]("data.tar")
>>> ds_names = ds.as_type(NameOnly) # Uses registered lensClasses
| Name | Description |
|---|---|
| Lens | A bidirectional transformation between two sample types. |
| LensNetwork | Global registry for lens transformations between sample types. |
Lens
lens.Lens(get, put=None)A bidirectional transformation between two sample types.
A lens provides a way to view and update data of type S (source) as if it were type V (view). It consists of a getter that transforms S -> V and an optional putter that transforms (V, S) -> S, enabling updates to the view to be reflected back in the source.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| S | The source type, must derive from PackableSample. |
required | |
| V | The view type, must derive from PackableSample. |
required |
Examples
>>> @lens
... def name_lens(full: FullData) -> NameOnly:
... return NameOnly(name=full.name)
...
>>> @name_lens.putter
... def name_lens_put(view: NameOnly, source: FullData) -> FullData:
... return FullData(name=view.name, age=source.age)Methods
| Name | Description |
|---|---|
| get | Transform the source into the view type. |
| put | Update the source based on a modified view. |
| putter | Decorator to register a putter function for this lens. |
get
lens.Lens.get(s)Transform the source into the view type.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| s | S | The source sample of type S. |
required |
Returns
| Name | Type | Description |
|---|---|---|
| V | A view of the source as type V. |
put
lens.Lens.put(v, s)Update the source based on a modified view.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| v | V | The modified view of type V. |
required |
| s | S | The original source of type S. |
required |
Returns
| Name | Type | Description |
|---|---|---|
| S | An updated source of type S that reflects changes from the view. |
putter
lens.Lens.putter(put)Decorator to register a putter function for this lens.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| put | LensPutter[S, V] | A function that takes a view of type V and source of type S, and returns an updated source of type S. |
required |
Returns
| Name | Type | Description |
|---|---|---|
| LensPutter[S, V] | The putter function, allowing this to be used as a decorator. |
Examples
>>> @my_lens.putter
... def my_lens_put(view: ViewType, source: SourceType) -> SourceType:
... return SourceType(field=view.field, other=source.other)LensNetwork
lens.LensNetwork()Global registry for lens transformations between sample types.
This class implements a singleton pattern to maintain a global registry of all lenses decorated with @lens. It enables looking up transformations between different PackableSample types.
Attributes
| Name | Type | Description |
|---|---|---|
| _instance | The singleton instance of this class. | |
| _registry | Dict[LensSignature, Lens] | Dictionary mapping (source_type, view_type) tuples to their corresponding Lens objects. |
Methods
| Name | Description |
|---|---|
| register | Register a lens as the canonical transformation between two types. |
| transform | Look up the lens transformation between two sample types. |
register
lens.LensNetwork.register(_lens)Register a lens as the canonical transformation between two types.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| _lens | Lens | The lens to register. Will be stored in the registry under the key (_lens.source_type, _lens.view_type). |
required |
Note
If a lens already exists for the same type pair, it will be overwritten.
transform
lens.LensNetwork.transform(source, view)Look up the lens transformation between two sample types.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| source | DatasetType | The source sample type (must derive from PackableSample). |
required |
| view | DatasetType | The target view type (must derive from PackableSample). |
required |
Returns
| Name | Type | Description |
|---|---|---|
| Lens | The registered Lens that transforms from source to view. |
Raises
| Name | Type | Description |
|---|---|---|
| ValueError | If no lens has been registered for the given type pair. |
Note
Currently only supports direct transformations. Compositional transformations (chaining multiple lenses) are not yet implemented.
Functions
| Name | Description |
|---|---|
| lens | Decorator to create and register a lens transformation. |
lens
lens.lens(f)Decorator to create and register a lens transformation.
This decorator converts a getter function into a Lens object and automatically registers it in the global LensNetwork registry.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| f | LensGetter[S, V] | A getter function that transforms from source type S to view type V. Must have exactly one parameter with a type annotation. |
required |
Returns
| Name | Type | Description |
|---|---|---|
| Lens[S, V] | A Lens[S, V] object that can be called to apply the transformation |
|
| Lens[S, V] | or decorated with @lens_name.putter to add a putter function. |
Examples
>>> @lens
... def extract_name(full: FullData) -> NameOnly:
... return NameOnly(name=full.name)
...
>>> @extract_name.putter
... def extract_name_put(view: NameOnly, source: FullData) -> FullData:
... return FullData(name=view.name, age=source.age)