I'm currently trying to overload MonadTransformer extraction functions. My current attempt was to place the inner-monad m as an instance of an associated type Result:
class ( Monad Result
, MonadTrans m
, MonadReader prefix m
, ) => FooReader prefix m where
type Result
runFooReader :: forall b. m b -> prefix -> Result b
instance Monad m => FooReader prefix (ReaderT prefix m)
type Result = m -- This is there the error is thrown
runFooReader = runReaderT
The only reason why Foo is shaped funny is due to the MonadTrans and MonadReader restrictions. Basically, this is forcing all associated type instances to be monomorphic types (correct?).
I then thought to redesign it, to make Result simply a polymorphic vairable:
...
class FooReader prefix m where
runFooReader :: forall b result. m b -> prefix -> result b
... but then in the instances, the types result and w (if it's ReaderT prefix w as m, for instance) will not unify. Is there any way to make this result varialbe / idea polymorphic, yet decidable?
Cleaning up the syntax errors and adding a kind annotation to
Result, we get this:And a more interesting error:
This is expanded in the GHC docs:
To explore the "it would compromise type safety" point, imagine this GHCi session:
You probably mean
type Result prefix (ReaderT prefix m) = m.There are still errors remaining. Notably, the kind of
mis inconsistent;MonadTransneeds a parameter of kind(* -> *) -> * -> *whileMonadReader's second parameter needs* -> *. I don't see why you needMonadTrans.I don't understand what you mean by "forcing all associated type instances to be monomorphic types"; the
Resulttype you've written isn't really a type function, because it doesn't have any parameters; there aren't any type variables on its LHS.Here's something that compiles: