[Haskell-cafe] Lifting IO actions into Applicatives

Tom Ellis tom-lists-haskell-cafe-2013
Tue Oct 1 12:35:57 UTC 2013

On Tue, Oct 01, 2013 at 03:17:40PM +0300, Yitzchak Gale wrote:
> Tom Ellis wrote:
> > Shouldn't it be an *Applicative* constraint?
> >
> >     class Applicative t => ApplicativeIO t where
> >         liftIO :: IO a -> t a
> >
> > and require that
> >
> >     liftIO (pure x) = pure x
> >     liftIO (f <*> x) = liftIO f <*> liftIO x
> >
> > Seems like ApplicativeIO makes more sense than MonadIO, which is
> > unnecessarily restrictive.  With planned Functor/Applicative/Monad shuffle,
> > the former could completely replace the latter.
> In fact, it even makes sense to define it as FunctorIO, with the only laws
> being that liftIO commutes with fmap and preserves id, i.e., that it is
> a natural transformation. (Those laws are also needed for ApplicativeIO
> and MonadIO.)

I think that law follows automatically from parametricity, doesn't it?

> Since Haskell is not dependently typed and we specify laws only as
> human-readable comments, should we define only FunctorIO and
> then just specify in the comments the additional laws that should
> be satisfied for Applicative and Monad? Or should we have equivalent
> definitions that differ only in the laws that are expected to be satisfied?
> Or should the different definitions have different superclass constraints?

In tackling such questions I think it would be useful to know how many such
instances there can be.  Can there be more than one morphism between two
monads?  Between two applicatives?  I would guess there are plenty of
examples of functors with more than one functor morphism (natural
transformation) between them.

Perhaps these questions are easy, but I don't know how to approach them.


More information about the Haskell-Cafe mailing list