【问题标题】:Snap Framework: How do I run IO within a handlerSnap 框架:如何在处理程序中运行 IO
【发布时间】:2012-11-25 19:22:49
【问题描述】:

这可能是一个简单的问题,我在 SO 上看到过类似的问题,但我仍然卡住了。

我正在尝试进行 HTTP 调用以提取另一个博客的内容并将其显示在我的页面上。这更像是一种学习练习。

这是我的处理程序

blog :: App1Handler ()
blog = do
  contents <- Requester.getUrl "http://someblog.com/"
  heistLocal (bindString "contents" contents) . render $ "blog"

Requester.getUrl 具有签名 getUrl :: String -> IO T.Text

我得到的错误是

src/Main.hs:50:15:
无法匹配预期类型 Handler App1 App1 t0' with actual typeIO T.Text'
在 `getUrl' 调用的返回类型中
在“do”块的 stmt 中:
内容 在表达式中:
做 { 内容 heistLocal (bindString "contents" 内容) 。渲染 $ "blog" }

据我所知,我被困在 IO monad 中,它需要类型 Handler App1 App1 t0。我已经尝试在某些地方粘贴 liftIO,但我对此感到很困惑。

谁能指出我正确的方向?

谢谢!

【问题讨论】:

  • 假设App1Handler 是支持IO 的典型monad 堆栈,它应该只是contents &lt;- liftIO $ Requester.getUrl "http://someblog.com/"。你试过吗?
  • 好吧,我会的。我完全糊涂了。我认为如果内容是 IO(a) 类型,那么我想像函子一样将 `heistLocal (bindString "contents")' 提升到它上面。谢谢哈马尔,我有一些阅读要做。另外,我感谢您在这里的所有回答 - 我一直遇到您回答的问题!

标签: haskell monads haskell-snap-framework


【解决方案1】:

你只需要liftIOIOgetUrl返回的动作,像这样:

contents <- liftIO $ Requester.getUrl "http://someblog.com/"

这里的推理很简单。你有一个App1Handler () 类型的do-block,这意味着 此 do 块中任何 &lt;- 语句的右侧必须具有 App1Handler a 类型。

然而,getUrl 返回IO Text,所以你需要一个函数来转换 IO aApp1Handler a 这正是 liftIO 所做的。

liftIO :: MonadIO m => IO a -> m a

【讨论】:

  • 太棒了,非常感谢!这源于我的误解,即在 do 块的每一行中可能有不同的 monad。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多