I’ve learned from the paper Effect Handlers in Haskell, Evidently mentioned in other thread that some effect libraries do use records instead of GADTs with multiple constructors for defining effects:
• The library interface […] is concise and arguably
simpler than other library interfaces for effect handlers.
In particular, effects are defined as a regular data type
with a field for each operation.
Other libraries typically require GADT’s [Kiselyov and
Ishii 2015], data types à la carte [Swierstra 2008; Wu
et al. 2014], or Template Haskell [Kammar et al. 2013]
to create new effects.
And they also use record field selectors when invoking operations, which actually seems quite Haskelly and ergonomic:
To perform operations, we pass the operation selector ask
with its argument to the perform function.