Andrew Thaddeus Martin
Andrew Thaddeus Martin

Reputation: 3285

Continuation Monad and Asynchronous Responses

Assume that we have three synchronous functions that get data over HTTP (These could be API calls internally):

lookupUser :: String -> IO UserId
lookupUserCity :: UserId -> IO City
lookupLocation :: City -> IO Location

So, I could just do monadic composition lookupLocation <=< lookupUserCity <=< lookupUser to get the location of a user. But, since each of these calls will block, this will prevent the rest of the program from running.

Apparently, continuations help solve this, but I can't find any real examples of it. I think that the signatures would be rewritten a -> ContT r IO b, but I don't see how you could achieve a callback-like pattern with this. If anyone could show me (1) how to write transform :: (a -> IO b) -> (a -> ContT r IO b) or (2) could link to a real example of someone doing this, I would be grateful.

Upvotes: 1

Views: 647

Answers (3)

agocorona
agocorona

Reputation: 166

The MFlow web framework permits that kind of monadic flow.

It simply block the process waiting for the next request. That can be done in an ordinary IO monad. but there are needed additional effects to manage the back button and for recovering the execution state after a timeout.

Upvotes: 0

cdk
cdk

Reputation: 6778

You can write transform even more generally then that:

transform :: Monad m => (a -> m b) -> a -> ContT r m b
transform k = lift . k

this works for any monad instead of only IO. But this is not what you really want. As Nikita Volkov mentions, continuations are not the solution if you want real asynchronous programming.

I'd recommend the async library as well.

Upvotes: 1

Nikita Volkov
Nikita Volkov

Reputation: 43309

Continuations are just a pattern of working with functions, they have nothing to do with asynchronicity.

What you need is forkIO or more high level abstractions presented by libraries like async.

Upvotes: 6

Related Questions