{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreidvdvypkyuozig3w7clx7ebvso57no6t5jkqzdkiczxnarn5wc66y",
    "uri": "at://did:plc:pi6woz4d47bkuws673w2il2r/app.bsky.feed.post/3mouesgcaftc2"
  },
  "path": "/t/error-ghc-91510-illegal-polymorphic-type/14304#post_8",
  "publishedAt": "2026-06-22T06:26:27.000Z",
  "site": "https://discourse.haskell.org",
  "textContent": "I had a niggle, so I came back to this.\n\nThe tweaks I introduced were an attempt to fix some errors that were actually due to the unconstrained type signatures on `id` and `(.)`; they aren’t relevant to the core issue here, so technically you can leave `Transform` unchanged and use\n\n\n    class    (forall x. f x) => Universally f\n    instance (forall x. f x) => Universally f\n\n\nto declare\n\n\n    instance (Category cat) => Category (Transform cat) where\n      type Objects (Transform cat) f = Universally (ObjectClass cat . f)\n\n\nHowever, those tweaks did point in the right direction semantically: if the true objects of the categories involved are only those satisfying the corresponding `Objects` constraints, then introducing an unconstrainable `x` as an object in the field of `Transform` is erroneous.\n\nThat said, imposing the constraint from `cat`, the _target_ category isn’t right either; that restricts us to transformations between endofunctors. The true fix requires `Transform` to know about the source category:\n\n\n    type Transform ::\n      (j -> j -> Type) ->\n      (k -> k -> Type) ->\n      (j -> k) ->\n      (j -> k) ->\n      Type\n    newtype Transform src tgt f g = Transform\n      {transform :: forall x. Objects src x => tgt (f x) (g x)}\n\n    instance (Category src, Category tgt) => Category (Transform src tgt) where\n      type Objects (Transform src tgt) f = ObjectClass src ==> ObjectClass tgt . f\n      id = Transform id\n      Transform g_h . Transform f_g = Transform (g_h . f_g)\n",
  "title": "Error GHC-91510: illegal polymorphic type"
}