Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 将结果缓存一定时间并返回缓存值_Haskell - Fatal编程技术网

Haskell 将结果缓存一定时间并返回缓存值

Haskell 将结果缓存一定时间并返回缓存值,haskell,Haskell,我想做以下事情:一个方法getSessionToken,它将: 如果“cachedSessionToken”过期(超过1小时前发出),则向服务器发出请求 一旦向服务器发出请求,它将结果保存到“变量”中,然后在调用getSessionToken时返回该结果 因此,我们的想法是缓存一个结果并在需要时返回,否则首先向服务器发出请求getSessionTokenRemote,缓存它,然后返回结果。我对getSessionTokenRemote的确切实现不感兴趣,但是,它可能是这样的: getSess

我想做以下事情:一个方法
getSessionToken
,它将:

  • 如果“
    cachedSessionToken
    ”过期(超过1小时前发出),则向服务器发出请求

  • 一旦向服务器发出请求,它将结果保存到“
    变量
    ”中,然后在调用
    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
?@Alex
newIORef
由提供。至于实现
CacheInfo
和朋友,那么。。。你试过什么?出了什么问题?我就是不知道如何“写入”CacheInfo,因为Haskell没有变量。如何以及在何处将值存储在Haskell中?我想这正是我想要的!tokenRef