Bundling and superclassing
re-xyr opened this issue · comments
daylily commented
Two disadvantages of type-level-list-based effect systems are that they do not support
- Bundling, as in
type MonadStateWriter s m = (MonadState s m, MonadWriter s m)
- Superclassing, as in
class MonadGet r m => MonadReader r m
Some possibilities of solving this:
-- A pseudo effect representing a bundle of several effects
data Bundle (es :: [Effect]) :: Effect
-- This will stuck if the user uses a polymorphic effect type
-- Most of the times they don't, but it is possible
type family e :> es :: Constraint where
Bundle es :> xs = es :>> xs
e :> xs = (Elem e xs, Super e xs)
-- A possibly better way is to just modify the (:>) typeclass
class e :> es where
instance {-# INCOHERENT #-} xs :>> es => Bundle xs :> es
instance Elem e es => e :> es
class Super e es => Elem e es
-- Users can define custom instances of this typeclass
-- to override the default behavior (no superclasses)
class Super e xs
instance {-# OVERLAPPABLE #-} Super e xs
daylily commented
Some initial tests show that while superclassing is easy to add as a nonbreaking change, bundling is largely breaking, bringing worse ergonomics.
daylily commented
Closed; wontfix