我正在获取此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
答案 0 :(得分:7)
详细阐述@Willem Van Onsem的观点...
即使getJSON
的值是不可变的,该不可变值也是而不是一个字节串。这是一个不可变的IO action ,它返回一个bytestring,但这并不意味着它每次都返回相同的bytestring。该动作是一个不可变的常量,但这并不意味着bytestring也是一个常量。
这类似于:
getLine :: IO String
getLine = ... some immutable IO action ...
虽然它本身是一个不可变的值(一个不可变的IO动作),但每次执行动作时都可以返回不同的字符串。
例如,以下自包含程序将返回两个不同的JSON字节串,one
和two
由两个HTTP请求产生,两个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"