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. Tom _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe