[Haskell-cafe] Lifting IO actions into Applicatives

Oliver Charles ollie
Tue Oct 1 08:15:47 UTC 2013


On 10/01/2013 07:58 AM, Michael Snoyman wrote:
> 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

Is it really necessary to have a type class to do this? You can always
just introduce 'io :: IO a -> Form a' to lift IO actions into a form.
Then you just have:

myBlogForm = Blog <$> titleForm <*> io getCurrentTime <*> contentsForm

In digestive-functors, we have the base monad in the type of the form
itself, so we provide 'monadic' which goes from
m (Form m a) -> Form m a (hand-waving as there are actually other type
constraints). You might get more power by following in those steps, and
having the aforementioned 'io' function actually be:

io :: IO (Form a) -> Form a

- ocharles


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: OpenPGP digital signature
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20131001/3d59b3aa/attachment.pgp>



More information about the Haskell-Cafe mailing list