[Haskell-cafe] Is `MonadBaseControl` dead?
compl.yue at icloud.com
Mon Jun 21 11:44:27 UTC 2021
This is also posted at https://www.reddit.com/r/haskell/comments/o4sggi/is_monadbasecontrol_dead/ <https://www.reddit.com/r/haskell/comments/o4sggi/is_monadbasecontrol_dead/> but I'd like to also seek wider help here.
(Background issue I'm facing: https://github.com/snapframework/snap-core/issues/309)
I think the functionality of [MonadUnliftIO](https://hackage.haskell.org/package/unliftio-core-0.2.0.1/docs/Control-Monad-IO-Unlift.html#t:MonadUnliftIO) is exactly what I want, but unfortunately [Snap](https://hackage.haskell.org/package/snap-core-126.96.36.199/docs/Snap-Core.html#t:Snap) appears not eligible for:
> the intuition is that a monad must have no monadic state, but may have monadic context. This essentially limits MonadUnliftIO to ReaderT and IdentityT transformers on top of IO.
Then I found `Snap` [has a MonadBaseControl instance](https://hackage.haskell.org/package/snap-core-188.8.131.52/docs/src/Snap.Internal.Core.html#line-347), and thought it should work for me. But sadly to find it [losing states](https://github.com/snapframework/snap-core/issues/309). Also I failed to find a user side example of `MonadBaseControl` on Github ([as there're only instance impl. hits](https://github.com/search?l=Haskell&q=org%3Asnapframework+liftBaseWith&type=Code)), so I have not way to verify whether that's due to my incorrect usage.
Any way quoting u/snoyberg : https://github.com/fpco/unliftio/issues/17#issuecomment-363655106
> Continuation-based monads cannot have instances of MonadUnliftIO, the same as MonadBaseControl and MonadMask.
Then I'm not sure `Snap`'s `MonadBaseControl` instance shall really work.
Also seems there had been debates I'm not aware of with clue at: https://github.com/fpco/unliftio/tree/master/unliftio#monad-control
> The main contention until now is that unlifting in a transformer like
> `StateT` is unsafe. This is not universally true: if only one action
> is being unlifted, no ambiguity exists. So, for example, `try :: IO a
> -> IO (Either e a)` can safely be unlifted in `StateT`, while `finally
> :: IO a -> IO b -> IO a` cannot.
> `monad-control` allows us to unlift both styles. In theory, we could
> write a variant of `lifted-base` that never does state discards, and
> let `try` be more general than `finally`. In other words, this is an
> advantage of `monad-control` over `MonadUnliftIO`. We've avoided
> providing any such extra typeclass in this package though, for two
> * `MonadUnliftIO` is a simple typeclass, easy to explain. We don't
> want to complicated matters (`MonadBaseControl` is a notoriously
> difficult to understand typeclass). This simplicity
> is captured by the laws for `MonadUnliftIO`, which make the
> behavior of the run functions close to that of the already familiar
> `lift` and `liftIO`.
> * Having this kind of split would be confusing in user code, when
> suddenly `finally` is not available to us. We would rather encourage
> [good practices](https://www.fpcomplete.com/blog/2017/06/readert-design-pattern)
> from the beginning.
> Another distinction is that `monad-control` uses the `MonadBase`
> style, allowing unlifting to arbitrary base monads. In this package,
> we've elected to go with `MonadIO` style. This limits what we can do
> (e.g., no unlifting to `STM`), but we went this way because:
> * In practice, we've found that the vast majority of cases are dealing
> with `IO`
> * The split in the ecosystem between constraints like `MonadBase IO`
> and `MonadIO` leads to significant confusion, and `MonadIO` is by
> far the more common constraints (with the typeclass existing in
So is `MonadBaseControl` dead or alive? Any user side example for it?
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Haskell-Cafe