packages feed

kleisli-0.0.1: README.md

# kleisli

Three newtype wrappers around `p a (f b)` with different type parameter orderings, enabling different type class instances depending on which parameter is last.

| Type | Parameter order | Primary instances |
|------|----------------|-------------------|
| `Kleisli p a f b` | functor in `b` | Functor, Applicative, Monad, MonadTrans, Distributive, Representable |
| `ProKleisli p f a b` | profunctor in `(a, b)` | Profunctor, Strong, Choice, Closed, Category, Arrow, Sieve, Representable |
| `ContraKleisli p b f a` | contravariant in `a` | Contravariant, Divisible, Decidable |

All three are representationally identical (`p a (f b)`) and connected by isomorphisms.

## Usage

When `p` is specialised to `(->)`, extensive instances are derived via `Star`, `ReaderT`, `Arrow.Kleisli`, and `Op`:

```haskell
import Data.Kleisli

-- Kleisli: use as a functor/monad in the result
k :: Kleisli (->) Int Maybe Int
k = fmap (+1) (Kleisli Just)

-- ProKleisli: use as a profunctor/arrow
p :: ProKleisli (->) Maybe Int Int
p = arr (+1) >>> arr (*2)

-- ContraKleisli: use as a contravariant functor
c :: ContraKleisli (->) Int Maybe Int
c = contramap (+1) (ContraKleisli Just)
```

## Type aliases

Convenient aliases eliminate common type parameters:

```haskell
type Kleisli'  p a b = Kleisli p a Identity b       -- no functor layer
type KleisliA  a f b = Kleisli (->) a f b           -- specialise profunctor to (->)
type KleisliA' a b   = KleisliA a Identity b        -- both specialised
```

Analogous aliases exist for `ProKleisli` and `ContraKleisli`.

## Isomorphisms

Lens `Iso`s convert between the three orderings:

```haskell
_Kleisli_ProKleisli    :: Iso (Kleisli p a f b) ... (ProKleisli p f a b) ...
_Kleisli_ContraKleisli :: Iso (Kleisli p a f b) ... (ContraKleisli p b f a) ...
```

Identity-eliminating isos map through the `Identity` wrapper:

```haskell
kleisli' :: Iso (Kleisli' p a b) ... (p a b) ...
```

## Building

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