# Sugar


Opt-in syntax-livability layer for nix-effects.

- `fx.sugar.do` / `fx.sugar.letM` — combinator forms
- `fx.sugar.operators.__div` — `/` as reverse-apply (bind)
- re-exports of `pure bind run handle map seq pipe kleisli`

See `book/src/sugar.md` for the opt-in matrix and caveats.

## `bind`

_Re-export of fx.kernel.bind. See fx.kernel for details._

## `do`

_do: build a composable Kleisli arrow `(a -> M b)` from a list of steps; plain functions `(a -> b)` are auto-lifted via `pure`, monadic functions `(a -> M b)` pass through. Apply the result to a seed to obtain a `Comp b`._

```
do : [a -> b | a -> M b] -> (a -> M b)
```

Use when steps form a linear pipeline that should remain
point-free and composable. Because `do` returns a Kleisli arrow,
two pipelines glue without lambdas:
`kleisli (do [f g]) (do [h i]) == do [f g h i]`. Data-last
argument order makes `map (do [validate enrich]) xs` natural.

Auto-lifting lets pure and effectful steps mix freely — runtime
dispatch via `isComp` decides whether to thread through `map` or
`bind`. An empty list gives the identity arrow `x: pure x`.

Prefer `steps` when discarding intermediate values is intentional
(effect sequencing). Prefer `kleisli` for a single binary
composition. Use `letM` when bound values are siblings rather
than a left-to-right pipeline.

## `handle`

_Re-export of fx.trampoline.handle. See fx.trampoline for details._

## `kleisli`

_Re-export of fx.kernel.kleisli. See fx.kernel for details._

## `letM`

_letM: `attrs`-based monadic binding — runs `bindAttrs attrs` to gather a record of results, then passes the record to continuation `k` for the next step._

```
letM : { name = Comp a } -> ({ name = a } -> Comp b) -> Comp b
```

Use when several independent computations must complete before a
single dependent step runs — `letM { a = ca; b = cb; } ({ a, b }: ...)`
replaces a nested `bind ca (a: bind cb (b: ...))` chain with a
flat record. Field order in the resulting record is unspecified;
ordering of side effects across fields is determined by
`bindAttrs`, not by the caller's attribute layout.

Prefer over `do` when the bound values are siblings rather than a
left-to-right pipeline. For a single bind, plain `bind` is
clearer.

## `map`

_Re-export of fx.kernel.map. See fx.kernel for details._

## `operators`

_operators: sugar operator overloads — currently `__div` aliasing `fx.kernel.bind` so `c / k` reads as `bind c k` in expression context._

Opt-in operator-style monadic composition. The attrset's
`__div` field is invoked by Nix's `/` operator when the LHS
is an attrset carrying `__div`. Use sparingly: operator
overloading is non-idiomatic in Nix and obscures dataflow for
readers unfamiliar with the convention. The combinator forms
(`bind`, `do`, `kleisli`) remain the canonical entry points.

## `pipe`

_Re-export of fx.kernel.pipe. See fx.kernel for details._

## `pure`

_Re-export of fx.kernel.pure. See fx.kernel for details._

## `run`

_Re-export of fx.trampoline.run. See fx.trampoline for details._

## `seq`

_Re-export of fx.kernel.seq. See fx.kernel for details._

## `steps`

_steps: sequence a list of `Comp` steps left-to-right via `bind`, returning a single composed `Comp`; each step receives the previous result, the seed is `pure null`._

```
steps : [a -> Comp b] -> Comp b
```

Use when only the side effects of each step matter — analogous to
Haskell's `sequence_`. The seed value is `pure null`, so the
first step's argument is `null`; discard it if the first step is
producer-shaped (`_: pure x`). An empty list returns `pure null`.

Prefer `do` for composable, point-free Kleisli pipelines that
thread values. Prefer `kleisli` when composing two Kleisli
arrows without an initial value, and `pipe` when threading a
non-monadic seed through effectful transforms.

## `types`

_types: refinement-applicable type wrappers — each primitive becomes a `__functor`-bearing record so `Int (n: n > 0)` chains another `refined` layer; `wrap` lifts an arbitrary type into the same callable form._

Sugar layer over `fx.types.refinement.refined`. Each entry
carries `__functor self pred = sugared (refined "name?" self pred)`,
so calling a type as a function tightens it with a predicate.
`__toString self = self.name` makes interpolated names
readable. The wrapped primitives (`Int`, `String`, `Bool`,
`Float`, `Path`, `Null`, `Unit`, `Any`) come from
`fx.types.primitives`; `wrap` lets callers lift any other
type into the same chainable shape.

## Source

- [`src/sugar/effects.nix`](https://github.com/kleisli-io/nix-effects/blob/main/src/sugar/effects.nix)
- [`src/sugar/operators.nix`](https://github.com/kleisli-io/nix-effects/blob/main/src/sugar/operators.nix)
- [`src/sugar/types.nix`](https://github.com/kleisli-io/nix-effects/blob/main/src/sugar/types.nix)

