{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreifp4pq4jog4annam26vln66ayczo5t7wxllkkepbkxcitneyazway",
    "uri": "at://did:plc:pi6woz4d47bkuws673w2il2r/app.bsky.feed.post/3mffcwnswohi2"
  },
  "path": "/t/improving-memory-with-better-abstractions/12350?page=2#post_35",
  "publishedAt": "2026-02-21T17:49:00.000Z",
  "site": "https://discourse.haskell.org",
  "tags": [
    "@Boolean"
  ],
  "textContent": "Indeed - `over each` does grant pointwise access, but the proposed `Endofunctor` class has different implications that the optics may not cover - same shape, different intent / use. I mostly intend it for internal use as machinery for defining different unit types that have associated algebras, so it is not necessarily meant for external use, like Data.ByteString.Internal.\n\nAs a relevant example of what I mean by same shape different use: lattices vs logics vs boolean algebras where technically they are all defined by the same five functions:\n\n\n    -- Actually a bounded distributive complementary lattice but who's counting\n    class (Eq a) => Lattice a where\n        meet :: a -> a -> a\n        top :: a\n        join :: a -> a -> a\n        bottom :: a\n        complement :: a -> a\n\n    class (Eq a) => Logical a where\n        conjunction :: a -> a -> a\n        tautology :: a\n        disjunction :: a -> a -> a\n        contradiction :: a\n        negation :: a -> a\n\n    -- *Pointwise* boolean eg hence 'ones' instead of 'one' or 'true'\n    -- Dont worry about it :)\n    class (Eq a) => Boolean a where\n        and :: a -> a -> a\n        ones :: a\n        or :: a -> a -> a\n        zeroes :: a\n        not :: a -> a\n\n\nSo you can see `meet` = `conjunction` = `and`, and so on, and we could choose any one of the three as the root to implement the others, but lattices are about order, logics allow for short circuiting, and pointwise algebras can efficiently be performed in parallel - same shape, different uses - and our endofunctor class is actually pretty concerned with that last one.\n\nIn particular, I’d actually like to be able to define a stricter subclass / constrain `Endofunctor` further, something more along the lines of this, which emphasizes that it is a pointwise _algebra_ eg `pointwise @Boolean @Bit complement bytes`:\n\n\n    {-# LANGUAGE AllowAmbiguousTypes #-}\n    {-# LANGUAGE UndecidableSuperClasses #-}\n\n    class (k u, k mu) => Pointwise (k :: Type -> Constraint) u mu where\n        pointwise :: (u -> u) -> mu -> mu\n        zipPointwise :: (u -> u -> u) -> mu -> mu -> mu\n\n    -- Trivially, every instance of an algebra is pointwise over itself\n    instance (k a) => Pointwise k a a where\n        pointwise = id\n        zipPointwise = id\n\n\nIt more strongly implies the link between `algebra u` and `algebra mu`, which goes further than just granting access to the subunits. Despite not actually constraining the function argument of pointwise to the algebra in question, partial type applications such as `pointwise @Boolean` do constrain the types, and we might find cases where we can `SPECIALIZE pointwise f = f` to eg to skip the individual pointwise mapping with a more efficient implementation when available, if that is possible like list fusion!\n\nHowever an actual `Pointwise` class is overkill and I’m not sure GHC can actually enforce this sort of specialization because eg type checking may fail to complete PLUS a lot of the time can just call `op mu` directly instead of `pointwise op mu` if you know what type `mu` is.",
  "title": "Improving `memory` with better abstractions"
}