[Haskell-cafe] Lifting IO actions into Applicatives
Alberto G. Corona
agocorona
Tue Oct 1 17:12:25 UTC 2013
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 at snoyman.com>
>
>
>
> On Tue, Oct 1, 2013 at 10:24 AM, Alexey Uimanov <s9gf4ult at 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 at 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
>>>
>>> [1] Full crazy definition is at:
>>> http://haddocks.fpcomplete.com/fp/7.4.2/20130922-179/yesod-form/Yesod-Form-Types.html#t:AForm
>>>
>>> _______________________________________________
>>> Haskell-Cafe mailing list
>>> Haskell-Cafe at haskell.org
>>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>>>
>>>
>>
>> _______________________________________________
>> Haskell-Cafe mailing list
>> Haskell-Cafe at haskell.org
>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>>
>>
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
--
Alberto.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20131001/f36a6b9d/attachment.htm>
More information about the Haskell-Cafe
mailing list