
All, For some project, I'm considering (again) to use an indexed state monad, which are now somewhat ergonomic to use with QualifiedDo. When looking into existing packages exposing relevant types/classes, I had some questions: 1. These packages provide something like ``` class IxFunctor f where imap :: (a -> b) -> f i j a -> f i j b class IxFunctor f => IxApplicative f where ... ``` Is this `IxFunctor` actually required/useful? It seems to me the implementation of `imap` for some `IxFunctor f` would be equal to `fmap` in the `Functor` implementation for `forall i j. f i j`. Hence, can `IxFunctor` be dropped in lieu of ``` class (forall i j. Functor (f i j)) => IxApplicative f where ... ``` 2. Existing packages predate MonadFail and QualifiedDo. The latter requires (in some cases) an implementation of `fail` and `mfix` to be provided by the module also providing `>>=` etc. I was wondering whether or not there need to be (or can be) `IxMonadFail` and `IxMonadFix` classes like ``` class IxMonad m => IxMonadFail m where ifail :: String -> m i j a class IxMonad m => IxMonadFix m where ifix :: (a -> m i j a) -> m i j a ``` I'm not sure it "makes sense" to have an `ifail` which returns an `m i j a` vs. having only a `MonadFail` (and hence `fail`) implementation for `m i i` only, taking into account the requirement for `fail f >>= k` to be equal to `fail f`, hence `ifail f >>=: k` to be equal to `ifail f`. I think the above question boils down to: is there any use in having `ifail :: String -> m i j a` next to `fail :: String -> m i i a`, or should (i)fail always be state-type-preserving? Similar doubts about `IxMonadFix m` vs. `MonadFix (m i i)`. Thanks for any insights, Nicolas