Reputation: 3285
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
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
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
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