packages feed

natural-0.5.0.1: README.md

# natural

Safe natural number, positive integer, and non-zero integer types with lens integration.

## Types

| Type | Range | Semigroup | Monoid identity |
|------|-------|-----------|-----------------|
| `Natural` | >= 0 | addition | 0 |
| `Positive` | >= 1 | multiplication | — |
| `NotZero` | /= 0 | addition | — |

Each type has corresponding newtype wrappers for alternative semigroups:

| Wrapper | Operation |
|---------|-----------|
| `ProductNatural` | multiplication |
| `MaxNatural` / `MinNatural` | max / min |
| `SumPositive` | addition |
| `MaxPositive` / `MinPositive` | max / min |
| `SumNotZero` | addition |
| `MaxNotZero` / `MinNotZero` | max / min |

## Optics

The library uses `lens` for type-safe conversions:

```haskell
-- Prisms for safe construction from integral types
(5 :: Integer) ^? _Natural   -- Just (Natural 5)
(-1 :: Integer) ^? _Natural  -- Nothing

(3 :: Integer) ^? _Positive  -- Just (Positive 3)
(0 :: Integer) ^? _Positive  -- Nothing

(7 :: Integer) ^? _NotZero   -- Just (NotZero True (Positive 7))
(0 :: Integer) ^? _NotZero   -- Nothing

-- Structural prisms
Natural 5 ^? successor       -- Just (Natural 4)
Natural 0 ^? successor       -- Nothing

Positive 3 ^? successor1     -- Just (Positive 2)
Positive 1 ^? successor1     -- Nothing

-- Isos between related types
Natural 4 ^. successorW      -- Positive 5
Natural 3 ^. naturalPositive -- Just (Positive 3)
Natural 3 ^. list            -- [(), (), ()]
```

## Type classes

Each type has `Has*` (lens) and `As*` (prism) classes with instances for
standard integral types (`Int`, `Integer`, `Word`, `Const`, `Identity`):

```haskell
class HasNatural a where
  natural :: Lens' a Natural

class AsNatural a where
  _Natural :: Prism' a Natural
```

## NotZero

A non-zero integer represented as a sign (`Bool`: `True` = positive) and a
magnitude (`Positive`):

```haskell
data NotZero = NotZero Bool Positive

positiveNotZero (Positive 5)  -- NotZero True (Positive 5)
negativeNotZero (Positive 3)  -- NotZero False (Positive 3)
notZeroInteger (NotZero False (Positive 3))  -- -3

-- Multiplication is always total
multiplyNZ (NotZero False (Positive 3)) (NotZero False (Positive 4))
  -- NotZero True (Positive 12)

-- Addition can produce zero
plusNZ (NotZero True (Positive 3)) (NotZero False (Positive 3))
  -- Nothing
```

## Building

```
cabal build
cabal test doctest
cabal bench
```