{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreihrycgkzn7mccpykzrki3j2sb23ox2ojiy62mzko3yx425hat4fwy",
    "uri": "at://did:plc:pi6woz4d47bkuws673w2il2r/app.bsky.feed.post/3mgyeuafzepa2"
  },
  "path": "/t/sneak-peek-bolt-math/13766#post_12",
  "publishedAt": "2026-03-13T14:35:12.000Z",
  "site": "https://discourse.haskell.org",
  "textContent": "I like a lot of the ideas here. But I’m also a bit worried for people reading complex code using this exact design because I’ve done a similar API before and it caused some issues.\n\nThe big pain point is that you have some lawless classes purely for operator overloading and then subclasses which add laws. This can make reading code incredibly annoying guesswork because you have to do class resolution in your head to figure out which laws apply. At least that happens to me, maybe others are smart enough to manage. When writing code I regularly forget to add the right bounds which cause subtle bugs, the language server can’t manage constraints automatically, and especially verbose/selfdesriptive class names can become quite painful when typed over and over.\n\nYou also already mentioned that lack of type inference can be painful, but I think the bigger pain is again during code reading. You gotta run type inference in your head, and now that’s also context dependent on the type class constraints in scope.\n\nAt a minimum I’d give homogeneous variants of the operators. When starting with a very loosely typed API I usually end up using a tightly typed wrappers 90+% of the time, and when the freely typed powerful version gets used that’s a warning signal to code readers that more complex typing is happening.\nAlso, maybe have bidirectional constraints? E.g. for `a + b == c`, you currently have `a b → c`, but adding `a c → b` and `b c → a` as required fundeps can help with reading and inference.",
  "title": "Sneak Peek: Bolt Math"
}