
From what you've said, it sounds like you can already write:
serverSide :: IO a -> Form a This seems elegant enough to me for your needs. Just encourage it as an idiom specific to Forms. myBlogForm = Blog <$> titleForm <*> serverSide getCurrentTime <*> contentsForm Could you abstract `serverSide` out into a typeclass, such as ApplicativeIO? Sure. but why bother? The point is, you've got the specialization you need already. -- Dan Burton On Tue, Oct 1, 2013 at 1:20 AM, Tom Ellis < tom-lists-haskell-cafe-2013@jaguarpaw.co.uk> wrote:
On Tue, Oct 01, 2013 at 09:29:00AM +0200, Niklas Haas wrote:
On Tue, 1 Oct 2013 02:21:13 -0500, John Lato
wrote: It's not a solution per se, but it seems to me that there's no need for the Monad superclass constraint on MonadIO. If that were removed, we could just have
class LiftIO t where liftIO :: IO a -> t a
and it would Just Work.
One concern with this is that it's not exactly clear what the semantics are on LiftIO (is liftIO a >> liftIO b equal to liftIO (a >> b) or not?) and the interaction between LiftIO and Applicative/Monad would have to be some sort of ugly ad-hoc law like we have with Bounded/Enum etc.
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.
Tom _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe