Haskell 将结果缓存一定时间并返回缓存值
我想做以下事情:一个方法Haskell 将结果缓存一定时间并返回缓存值,haskell,Haskell,我想做以下事情:一个方法getSessionToken,它将: 如果“cachedSessionToken”过期(超过1小时前发出),则向服务器发出请求 一旦向服务器发出请求,它将结果保存到“变量”中,然后在调用getSessionToken时返回该结果 因此,我们的想法是缓存一个结果并在需要时返回,否则首先向服务器发出请求getSessionTokenRemote,缓存它,然后返回结果。我对getSessionTokenRemote的确切实现不感兴趣,但是,它可能是这样的: getSess
getSessionToken
,它将:
- 如果“
”过期(超过1小时前发出),则向服务器发出请求cachedSessionToken
- 一旦向服务器发出请求,它将结果保存到“
”中,然后在调用变量
时返回该结果getSessionToken
getSessionTokenRemote
,缓存它,然后返回结果。我对getSessionTokenRemote
的确切实现不感兴趣,但是,它可能是这样的:
getSessionTokenRemote :: IO String
-- or just
getSessionTokenRemote :: String
getGetSessionTokenRemote :: IO (IO String)
getGetSessionTokenRemote = getSessionTokenRemote <$> newIORef emptyCacheInfo
只要最合适
我想知道,在Haskell这样的纯函数式语言中如何实现这一点?如果要
getSessionTokenRemote
写入变量,必须传递一个变量,例如,给它一个类型,如:
type CacheInfo = {- you've got to fill this bit in -}
getSessionTokenRemote :: IORef CacheInfo -> IO String
一旦您采用这样的类型,实现就不会太困难了
如果要实现隐藏,另一种方法是编写一个值,该值生成getSessionTokenRemote
值。假设上面类型的内部实现和一些空缓存值emptyCacheInfo
,可以这样做:
getSessionTokenRemote :: IO String
-- or just
getSessionTokenRemote :: String
getGetSessionTokenRemote :: IO (IO String)
getGetSessionTokenRemote = getSessionTokenRemote <$> newIORef emptyCacheInfo
getGetSessionTokenRemote::IO(IO字符串)
getGetSessionTokenRemote=getSessionTokenRemote newIORef emptyCacheInfo
这是一个
IO
操作,当执行该操作时,会生成一个会话令牌获取操作,该操作带有一个新缓存。Haskell确实有状态变量,但它们是“托管”的。它们不可避免地运行在一些单子中,您必须显式地读取/写入它们IORef
、MVar
、TVar
和朋友都是“托管参考”(我第一次听到Clojure社区使用这个词)
下面是一个可怕的简化示例,演示了如何使用ref类型进行设置
import Data.IORef
import Network.HTTP
data SessionToken = SessionToken {
_timeHours :: Int
, _token :: String
}
getSessionToken :: IORef SessionToken -> IO String
getSessionToken cacheRef = do
cachedToken <- readIORef cacheRef
if _timeHours cachedToken > 1
then do
newToken <- getSessionTokenRemote
writeIORef cacheRef newToken
return $ _token newToken
else return $ _token cachedToken
getSessionTokenRemote :: IO SessionToken
getSessionTokenRemote = do
tokenRequest <- simpleHTTP $ getRequest "http://jtobin.ca/sample_token.txt"
token <- getResponseBody tokenRequest
return $ SessionToken 0 token
main :: IO ()
main = do
tokenRef <- newIORef $ SessionToken 0 "my token"
getSessionToken tokenRef >>= putStrLn
writeIORef tokenRef $ SessionToken 2 "my token"
getSessionToken tokenRef >>= putStrLn
import Data.IORef
导入网络.HTTP
数据会话肯=会话肯{
_timeHours::Int
,_标记::字符串
}
getSessionToken::IORef SessionToken->IO字符串
getSessionToken cacheRef=do
cachedToken 1
那就做吧
newToken=putStrLn
请您解释一下如何实现键入CacheInfo
、newIORef
和emptyCacheInfo
?@AlexnewIORef
由提供。至于实现CacheInfo
和朋友,那么。。。你试过什么?出了什么问题?我就是不知道如何“写入”CacheInfo,因为Haskell没有变量。如何以及在何处将值存储在Haskell中?我想这正是我想要的!tokenRef