0

我正在获取这个 JSON,将它用于一些计算,并希望返回一个结果,也使用 warp。现在 getJSON 显然是不可变的,根本不会改变。如何在每个 http 请求上重新评估 getJSON?最干净的方法是什么?

 getJSON :: IO B.ByteString
    getJSON = do
                let authHeader = ("Authorization", token)
                request' <- parseRequest jsonURL
                let request = request' { requestHeaders = [authHeader] }
                manager <- newManager tlsManagerSettings
                resp <- httpLbs request manager
                return $ responseBody resp
4

1 回答 1

7

详细说明@Willem Van Onsem 的观点......

即使 的值getJSON是不可变的,该不可变的值也不是字节串。这是一个不可变的 IO操作,它返回一个字节串,但这并不意味着它每次都返回相同的字节串。动作是一个不可变的常量,但这并不意味着字节串也是一个常量。

这类似于以下方式:

getLine :: IO String
getLine = ... some immutable IO action ...

虽然它本身是一个不可变的值(一个不可变的 IO 操作),但每次执行该操作时可以返回不同的字符串。

例如,以下自包含程序将返回两个不同的 JSON 字节串,one并由two两个 HTTP 请求产生,均由相同的getJSON操作发起:

import qualified Data.ByteString.Lazy.Char8 as B
import Control.Concurrent (threadDelay)
import Network.HTTP.Client

jsonURL :: String
jsonURL = "http://time.jsontest.com"

getJSON :: IO B.ByteString
getJSON = do
  request <- parseRequest jsonURL
  manager <- newManager defaultManagerSettings
  resp <- httpLbs request manager
  return $ responseBody resp

main = do
  one <- getJSON
  threadDelay (3*10^6)  -- delay three seconds
  two <- getJSON
  putStrLn $ "one was:\n" ++ B.unpack one ++ "\n"
  putStrLn $ "two was:\n" ++ B.unpack two ++ "\n"
于 2018-02-16T23:17:35.547 回答