在包的Control.Proxy
教程中pipes-3.1.0
,作者提供了这个功能:
cache :: (Proxy p, Ord key) => key -> p key val key val IO r
cache = runIdentityK (loop M.empty) where
loop _map key = case M.lookup key _map of
Nothing -> do
val <- request key
key2 <- respond val
loop (M.insert key val _map) key2
Just val -> do
lift $ putStrLn "Used cache!"
key2 <- respond val
loop _map key2
因为我想有一个并发的应用程序缓存请求,所以我有以下数据类型
newtype Cache k v = Cache (MVar (M.Map k v))
现在我想要一个cache
带有签名的新函数
cache :: (Proxy p, Ord k) => Cache k v -> k -> p k v k v IO r
cache (Cache c) k = readMVar c >>= \m -> runIdentityK $ loop m k
where loop m key = case M.lookup key m of
Nothing -> do
val <- request key
respond val >>= loop (M.insert key val m)
Just val -> respond val >>= loop m
但是,这无法进行类型检查,因为readMVar
它在IO
monad 中,并且runIdentityK
在Proxy p => p k v k v IO r
monad 中。当然我可以readMVar
进入这个代理单子,因为它是一个变压器IO
,但我找不到合适的组合器。