【问题标题】:Continuation Monad and Asynchronous Responses延续单子和异步响应
【发布时间】:2014-08-10 00:37:36
【问题描述】:

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

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

所以,我可以只做一元组合lookupLocation <=< lookupUserCity <=< lookupUser 来获取用户的位置。但是,由于这些调用中的每一个都会阻塞,这将阻止程序的其余部分运行。

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

【问题讨论】:

    标签: haskell asynchronous continuations


    【解决方案1】:

    MFlow Web 框架允许这种单子流。

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

    【讨论】:

      【解决方案2】:

      你可以写成transform 甚至更一般:

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

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

      我也推荐异步库。

      【讨论】:

        【解决方案3】:

        Continuations 只是一种使用函数的模式,它们与异步无关。

        您需要的是forkIOasync 等库提供的更多高级抽象。

        【讨论】:

          猜你喜欢
          • 2023-03-22
          • 2010-10-14
          • 2011-02-09
          • 1970-01-01
          • 2011-10-13
          • 2014-07-22
          • 1970-01-01
          • 2014-12-07
          • 1970-01-01
          相关资源
          最近更新 更多