当前位置: 首页 > 知识库问答 >
问题:

如何使用"IO String"作为一个HTTP响应在哈斯塔克?

郑衡
2023-03-14

我正在使用HDBC从数据库检索数据,然后尝试使用Happstack将这些数据发送到web客户端。

myFunc :: Integer -> IO String
myFunc = ... fetch from db here ...

handlers :: ServerPart Response
handlers =
    do decodeBody (defaultBodyPolicy "/tmp/" 0 1000 1000)
       msum [ 
                dir "getData" $ ok $ toResponse $ myFunc $ toInteger 1
            ]

mainFunc = simpleHTTP nullConf handlers

当我构建上面的代码我得到这个错误:

没有因使用“toResponse”而产生的(ToMessage(IO字符串))实例

我试了什么?

  1. 我尝试将IO String转换为String(例如使用liftIO)。
  2. 我试图在这里找到任何类似的问题。
  3. 我试图找到一个类似的例子在幸福堆栈速成班。
  4. 我谷歌了所有不同组合的相关关键词。

提前感谢。

共有1个答案

阎知
2023-03-14

您必须围绕以下事实设计处理程序,即从数据库获取数据是一种神奇的操作,它可能无法满足您的期望。(例如,您的数据库可能会崩溃。)这就是为什么它的结果被用作IO,这是monad的一种特殊情况。

单子是一个颈很窄的罐子,非常窄,一旦你把东西放进去,你就不能把它打开。(除非它碰巧也是一个comonad,但这完全是另一回事,IOServerPart都不是这样)因此,您永远不会将IO字符串转换为字符串。并不是说你不能,但是你的程序会变得不正确。

你的情况有点棘手,因为你有两个单子在那里:IOServerPart。幸运的是,ServerPart建立在IO的基础上,它“更大”,在某种意义上可以吸收IO:我们可以将一些IO放入ServerPart中,它仍然是ServerPart,因此我们可以将它交给simpleHTTP。在happstack中,此转换可以通过require功能完成,但也有一个更通用的解决方案,涉及monad变压器和lift

让我们先看一下解决方案:<代码>需要<代码> >。其类型(简化为我们的情况)为:

IO (Maybe a) -> (a -> ServerPart r) -> ServerPart r

-因此,它需要一个带有一些参数的IOjar,并使其适用于生活在ServerPartjar中的函数。我们只需要稍微调整类型并创建一个lambda抽象:

myFunc :: Integer -> IO (Maybe String)
myFunc _ = return . Just $ "A thing of beauty is a joy forever."

handlers :: ServerPart Response
handlers = require (myFunc 1) $ \x ->
    do decodeBody (defaultBodyPolicy "/tmp/" 0 1000 1000)
       msum [
                dir "getData" $ ok $ toResponse x
            ]

mainFunc = simpleHTTP nullConf handlers

如你所见,我们必须做两个修改:

>

  • 调整myFunc,使其返回也许,这是要求所必需的。这是一个更好的设计,因为myFunc现在可能以两种方式失败:

    • 作为一个也许,它可能返回没什么,意思是404之类的。这是相当常见的情况。
    • 作为IO,它可能会出错,这意味着数据库崩溃。现在是提醒运营模式团队的时候了。

    调整处理程序,使myFunc位于它们的外部。可以更具体地说:从处理程序中提取myFunc。这就是为什么这种语法被称为lambda抽象。

    require是专门在happstack中处理单子的方法。一般来说,这只是将单子转换为较大单子的一种情况,这是通过lift实现的。提升的类型(再次简化)为:

    IO String -> ServerPart String
    

    因此,我们只需将myFunc 1::IO字符串值提升到右侧monad,然后使用

    myFunc :: Integer -> IO String
    myFunc _ = return $ "Its loveliness increases,.."
    
    handlers :: ServerPart Response
    handlers = lift (myFunc 1) >>= \x ->
        do decodeBody (defaultBodyPolicy "/tmp/" 0 1000 1000)
           msum [
                    dir "getData" $ ok $ toResponse x
                ]
    
    mainFunc = simpleHTTP nullConf handlers
    

    就这么简单。我再次使用了相同的lambda抽象技巧,但您也可以使用do表示法:

    myFunc :: Integer -> IO String
    myFunc _ = return $ "...it will never pass into nothingness."
    
    handlers :: ServerPart Response
    handlers = do
        x <- lift (myFunc 1)
        decodeBody (defaultBodyPolicy "/tmp/" 0 1000 1000)
        msum [
                dir "getData" $ ok $ toResponse x
             ]
    
    mainFunc = simpleHTTP nullConf handlers
    

    P. S.回到大小罐的故事:您可以将IO放入ServerPart,正是因为ServerPart也是一个IOmonad-它是MonadIO类的实例。这意味着你可以在IO中做的任何事情,你也可以在ServerPart中做,并且,除了一般的提升之外,还有一个专门的liftIO函数,您可以在我使用提升。您可能会遇到许多其他monad,它们是MonadIO的实例,因为这是在大型应用程序中构造代码的一种方便方法。

    在您的特殊情况下,我仍然会坚持使用require的方式,因为我认为这是happstack的设计者想要实现的。不过,我对happstack的知识不是特别渊博,所以我可能错了。

    就这样。快乐的黑客!

  •  类似资料:
    • 是否可以在不将此请求发送到服务器的情况下截获通过Charles的请求并立即返回500个错误代码? 找不到这方面的任何信息。所有资源建议等待响应,然后将HTTP响应代码更改为500。

    • vesta 是一款集容器扫描,Docker和Kubernetes配置基线检查于一身的工具。检查内容包括镜像或容器中包含漏洞版本的组件,Docker以及Kubernetes的危险配置。vesta同时也是一个灵活,方便的工具,能够在各种系统上运行,机器内1 vCPU, 2G Memory即可,包括但不限于Windows,Linux以及MacOS 检查项 Scan 扫描通过主流安装方法安装程序的漏洞 a

    • 问题内容: 我正在试验来自简单NodeJS HTTP服务器的各种响应。我试图实现的效果是更快地呈现网页。由于响应是使用(对吗?)流式传输到浏览器的,所以我想我可以先呈现页面布局,而在延迟之后再呈现其余数据。 问题是,它好像没有发送响应,直到除非已写入的数据是足够长的时间,所以例如,而不是说,会做的伎俩。 Node是否正在缓冲我的写操作,直到数据足够大到可以发送为止?如果是这样,块大小是否可以配置?

    • 我想用响应替换http异常,也就是说,我使用我想返回的responseentity,例如409如果没有通过名称找到用户,509如果没有通过邮件找到用户,我可以确定responseentity中的错误号及其描述吗?如果有,可以举例说明吗?

    • 我正在使用Spring Web创建一个rest资源。我用Java创建了类似于Json响应的文档对象。当我使用String.class作为响应类型时,我从请求中获取响应。当我更改对我创建的类的响应时,boy是null。 这是我的httpgetter Json文档 函数调用 JSON响应

    • 问题内容: 我知道曾经有一种使用apache commons来获取它的方法,如此处记录的:http : //hc.apache.org/httpclient-legacy/apidocs/org/apache/commons/httpclient/HttpMethod.html 和此处的示例: http://www.kodejava.org/examples/416.html 但我认为这已被弃用。