packages feed

polytropos-profunctors-0.1.0.2: README.md

# polytropos-profunctors

Pure profunctor optics integration for [polytropos](https://github.com/NadiaYvette/polytropos) open records and variants via `profunctors`.

## Overview

`polytropos-profunctors` provides first-class profunctor lenses and prisms (`Lens`, `Prism`, `view`, `preview`, `review`, `over`, `set`) operating directly over Polytropos's unboxed `SmallArray` memory layout.

Unlike `polytropos-optics` (which relies on `optics-core`) or `polytropos-lens` (which depends on Edward Kmett's `lens`), `polytropos-profunctors` requires only the lightweight `profunctors` package (`Data.Profunctor.Strong`, `Data.Profunctor.Choice`), making it ideal for categorical frameworks, arrow engines (such as Kernmantle), and streaming pipelines.

## Features

- **`fieldLens`**: High-level typed profunctor lens focusing on an open record field via compile-time `FieldIndex`.
- **`ctorPrism`**: High-level typed profunctor prism focusing on an open variant constructor via compile-time `ConstructorIndex`.
- **`slotLens` & `typedSlotLens`**: Low-level profunctor lenses focusing on physical array slots with dual-mode in-place updates.
- **`variantPrism` & `typedVariantPrism`**: Low-level profunctor prisms matching unboxed constructor tags in $O(1)$ time.

## Quick Example

```haskell
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -fplugin=Polytropos.Plugin #-}

import Polytropos
import Polytropos.Profunctors

type Person = Record '["name" ':= String, "age" ':= Int]

alice :: Person
alice = REC { name = "Alice", age = 30 }

-- Read field via profunctor lens:
aliceAge :: Int
aliceAge = view (fieldLens (Field @"age")) alice  -- 30

-- Update field via profunctor lens:
olderAlice :: Person
olderAlice = over (fieldLens (Field @"age")) (+ 1) alice  -- age = 31

-- Variant constructor matching:
type Shape = Variant '["Circle" ':= '["radius" ':= Double]]

myCircle :: Shape
myCircle = VAR { Circle = REC { radius = 5.0 } }

circlePayload :: Maybe (Record '["radius" ':= Double])
circlePayload = preview (ctorPrism (Field @"Circle")) myCircle
```

## License

Dual-licensed under `EUPL-1.2 OR Apache-2.0`.