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
```