10

Is there somewhere in Hackage a typeclass analogous to MonadIO but for Applicatives, that allows one to easily lift IO actions to "applicative composition stacks" based on IO?

If such a typeclass existed, would it be made obsolete by the implementation of the Applicative-Monad Proposal? Does the proposal involve a relaxation on the Monad constraint for MonadIO?

jub0bs
  • 60,866
  • 25
  • 183
  • 186
danidiaz
  • 26,936
  • 4
  • 45
  • 95
  • 1
    I think relaxing the `Monad` constraint is worth considering. – Tom Ellis Sep 26 '14 at 17:58
  • 3
    In case people are wondering, the laws would be `liftAIO (pure r) = pure r` and `liftAIO (f <*> x) = liftAIO f <*> liftAIO x` – Gabriella Gonzalez Sep 26 '14 at 20:15
  • I think the answer the question "Is there somewhere in Hackage a typeclass analogous to MonadIO but for Applicatives?" is "No" (I couldn't find anything, at least), but that doesn't mean @GabrielGonzalez won't write a blog post about it at some point. – bheklilr Sep 26 '14 at 21:53
  • Relaxing the `Monad` constraint for `MonadIO` would be problematic if for no other reason than that there is a lot of code out there with type signatures like `(MonadIO m) => ... -> m ...` that requires `m` to be a `Monad` (for reasons unrelated to `liftIO`). But `MonadIO m` is not equivalent to `(Monad m, ApplicativeIO m)` either, see my answer below. – Reid Barton Sep 27 '14 at 00:57

1 Answers1

5

There was a related discussion on haskell-cafe a year ago. In the Reddit comments I gave an example of a natural transformation (g) from IO to another monad that is an applicative functor morphism (i.e., satisfies the laws that Gabriel Gonzalez mentioned) but is not a monad morphism (it does not satisfy the additional law relating to >>=). So, even in a world with AMP, ApplicativeIO m and MonadIO m are really different things, even when m is a Monad!

In an ideal world you'd have a setup like this:

class Functor f => FunctorIO f where
    liftIO :: IO a -> f a
    -- such that liftIO is a natural transformation (automatic, by parametricity)

class (Applicative f, FunctorIO f) => ApplicativeIO f where
    --   ... and liftIO is an applicative functor morphism

class (Monad f, ApplicativeIO f) => MonadIO f where
    --   ... and liftIO is a monad morphism

and magical fairies would define ApplicativeIO and MonadIO instances exactly when the corresponding laws were satisfied.

Reid Barton
  • 14,951
  • 3
  • 39
  • 49