{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreifqbu2taa2ufsl6aiwo6lwxuty5sggvo3xm5hxd7vvhm5jl37gmby",
    "uri": "at://did:plc:pi6woz4d47bkuws673w2il2r/app.bsky.feed.post/3mh5kpipby322"
  },
  "path": "/t/sneak-peek-bolt-math/13766#post_19",
  "publishedAt": "2026-03-15T22:48:06.000Z",
  "site": "https://discourse.haskell.org",
  "tags": [
    "github.com/tonyday567/numhask",
    "Is QuotientField an Action? Are all our deconstructions reconstructed via actions?",
    "tonyday567",
    "[post",
    "post"
  ],
  "textContent": "Yes, I went looking in numhask and you might be right.\n\nQuotientField seems to work very well in an action context, but the other heterogeneous bits also look suspiciously like actions in disguise.\n\ngithub.com/tonyday567/numhask\n\n####  Is QuotientField an Action? Are all our deconstructions reconstructed via actions?\n\nopened 10:41PM - 15 Mar 26 UTC\n\n tonyday567 \n\n# Is QuotientField an Action? I've oscillated back and forth on where to put `Q…uotientField` in the numhask abstraction tower. A recent post got me thinking that a `QuotientField` is an action in disguise. The current signature: ```haskell properFraction :: a -> (Whole a, a) ``` is certainly a source of confusion. It is not a signature designed to compose. If you change the signature to: ```haskell properFraction :: (Whole a, a) -> (Whole a, a) ``` composable, and you recover the old meaning with `\\x -> properFraction (zero, x)`. This also starts to look like an action. The `Whole a` part is acting on the `a` part, accumulating the integer component as you compose (or being lazy and deferring?). The maths of `floor`, `ceiling`, `truncate` and `round` are neat: just the fixpoints of `properFraction` under different constraints on the remainder — where it lands in `[0,1)`, `(-1,0]`, toward zero, or nearest integer or rounding. Implementation is still the same, but these become just helpers. ### choosing what is \"proper\" There are many situations where another container for the decomposition is more appropriate than `(,)`: - `Either (Whole a) a`** — separate paths for integral or fractional computations - `These (Whole a) a`** — a natural representation of the general case: exact integer (`This n`), pure fractional (`That r`), or both (`These n r`), which is a common interpretation. ## Basis and Direction If I squint, `Basis` looks like the same pattern. When we decompose, we reconstruct via an action. ```haskell class (Distributive (Mag a)) => Basis a where type Mag a :: Type type Base a :: Type magnitude :: a -> Mag a basis :: a -> Base a ``` The reconstruction law `a == magnitude a *| basis a` says that `magnitude` and `basis` are projections of a decomposition that reassembles via the multiplicative action `*|`. And `coord` makes this explicit: ```haskell coord x = radial x *| ray (azimuth x) ``` `azimuth x` extracts the angle, `ray` lifts it back to a unit-magnitude coordinate via the retraction `ray . angle == basis`, and `radial x *|` scales by the magnitude via the action. The action isn't incidental — it is the mechanism of reconstruction. `Direction` introduces a retraction of the coordinate space onto a unit-magnitude subspace. `ray . angle == basis` says: project to unit direction, convert to angle and back, equals just projecting to unit direction. ## action as organizing principle If every decomposition in numhask reconstructs via an action, then maybe that action is the primitive of the class. This suggests a reorientation of the API: - the action as the primitive reconstruction mechanism - decompose as the dual — a law-abiding way to split - **build/observe** as a vocabulary or semantic Then `ray`/`angle`, `polar`/`coord`, `properFraction` all start to resemble a pattern that can be extended if you need to. Instead of a collection of ad-hoc decomposition classes, you'd have a principled API organised around this structure. Any new decomposition has a clear template: what's the action that reconstructs. It's a big move, but I've been circling this drain for a while now.",
  "title": "Sneak Peek: Bolt Math"
}