In MFow there is a Monad instance for formlets that make a lot of sense. Apart from using liftIO inside an applicative formlets


it can do it that way also:

myBlogForm = do
     t <- liftIO getTime
     Blog <$> titleForm <*> return t <*> contentsForm

Which may look contrived, but instead of using return t, we can display for the user something interesting in that place.
There are other  dynamic things, like asking different questions depending on previous responses thanks to the monad instance :

http://haskell-web.blogspot.com.es/2013/06/the-promising-land-of-monadic-formlets.html


2013/10/1 Michael Snoyman <michael@snoyman.com>



On Tue, Oct 1, 2013 at 10:24 AM, Alexey Uimanov <s9gf4ult@gmail.com> wrote:
Maybe this is needed new typeclass ApplicativeTrans?



There's actually no problem with defining a MonadTrans instance for non-monads. Obviously this can't follow the laws directly (since they're defined in terms of monadic bind and return), but I think we could probably state Applicative versions of those laws (assuming I haven't made a stupid mistake):

lift . pure = pure
lift (x <*> y) = lift x <*> lift y

Michael
 
2013/10/1 Michael Snoyman <michael@snoyman.com>
I'm wondering if anyone's run into this problem before, and if there's a common solution.

In Yesod, we have applicative forms (based originally on formlets). These forms are instances of Applicative, but not of Monad. Let's consider a situation where we want to get some user input to fill out a blog post datatype, which includes the current time:

data Blog = Blog Title UTCTime Contents

myBlogForm :: Form Blog
myBlogForm = Blog <$> titleForm <*> something <*> contentsForm

The question is: what goes in something? Its type has to be:

something :: Form UTCTime

Ideally, I'd call getCurrentTime. The question is: how do I lift that into a Form? Since Form is only an Applicative, not a Monad, I can't create a MonadIO instance. However, Form is in fact built on top of IO[1]. And it's possible to create a MonadTrans instance for Form, since it's entirely possible to lift actions from the underlying functor/monad into Form. So something can be written as:

something = lift $ liftIO getCurrentTime

This works, but is unintuitive. One solution would be to have an ApplicativeIO typeclass and then use liftIOA. My questions here are:

1. Has anyone else run into this issue?
2. Is there an existing solution out there?

Michael


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe



_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe



_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe




--
Alberto.