如何在Haskell中存储函数的返回参数

时间:2016-04-20 03:47:44

标签: haskell

我打算将withResponse的第三个参数的返回类型用于另一个函数brRead。我收到这个错误:

  

输入`)解析错误'失败,模块加载:无。

从以下代码(使用Network.HTTP.Client):

startOn url = do
    man <- newManager defaultManagerSettings
    req <- parseUrl url
    withResponse req man (let x = return (withResponse req man))
    brRead x
    return $ read

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

你很困惑,而且需要稍微解压一下。

虽然使用IOIORef monad内部工作时有一种通用方法可以将输入参数隐藏起来,但我不会告诉你,因为:

  1. 没有必要做任何偷偷摸摸的事情,因为withResponse的返回值是其第三个参数返回的。
  2. 它不会帮助您,因为如果您从Response BodyReader中取出withResponse,它将被关闭,您将无法阅读它。
  3. 首先,withResponse的类型是:

    withResponse :: Request -> Manager -> (Response BodyReader -> IO a) -> IO a
    

    现在,description of withResponse清楚地表明Response BodyReader对象仅在withResponse的操作中有效。因此,如果您尝试将该对象从withResponse中取出,那么您将无法阅读该对象。 Response BodyReader对象已经关闭。

    相反,您应该做的是创建一个使用响应并对其执行某些操作的函数,并传递该函数。由于你声称要做的只是一次就回复brRead,你可以这样做:

    startOn url = do
        man <- newManager defaultManagerSettings
        req <- parseUrl url
        read <- withResponse req man (brRead . responseBody)
        return $ read
    

    这将只返回给定网址的第一个ByteString块,但如果您只需要,那就没问题了。如果你在这里尝试做的是返回整个ByteString的回复,那么已经有了便利功能 - httpLbs

    startOn url = do
        man <- newManager defaultManagerSettings
        req <- parseUrl url
        response <- httpLbs req man
        return $ responseBody response