连续Monad和异步响应

时间:2014-06-19 12:56:51

标签: haskell asynchronous continuations

假设我们有三个通过HTTP获取数据的同步函数(这些函数可能是内部的API调用):

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

因此,我可以使用monadic composition lookupLocation <=< lookupUserCity <=< lookupUser来获取用户的位置。但是,由于每个调用都会阻塞,这将阻止程序的其余部分运行。

显然,延续有助于解决这个问题,但我无法找到任何真实的例子。我认为签名会被重写a -> ContT r IO b,但我不知道如何用这个来实现类似回调的模式。如果有人能告诉我(1)如何写transform :: (a -> IO b) -> (a -> ContT r IO b)或(2)可以链接到有人这样做的真实例子,我将不胜感激。

3 个答案:

答案 0 :(得分:6)

延续只是一种处理功能的模式,它们与异步性无关。

您需要的是forkIO或更多高级抽象,例如async等。{/ p>

答案 1 :(得分:1)

您可以更频繁地编写transform

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

这适用于任何monad而不仅仅是IO。但这不是你真正想要的。正如Nikita Volkov所提到的,如果你想要真正的异步编程,延续不是解决方案。

我也推荐使用异步库。

答案 2 :(得分:0)

MFlow Web框架允许这种monadic流程。

它只是阻止等待下一个请求的进程。这可以在普通的IO monad中完成。但是需要额外的效果来管理后退按钮以及在超时后恢复执行状态。