在Control.Proxy
教程为pipes-3.1.0
包代理,作者提供了这样的功能:使用管道/并发MVars
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
单子,并runIdentityK
在Proxy p => p k v k v IO r
单子。当然,我可以将readMVar
放入此代理单元,因为它是一个超过IO
的变压器,但我找不到合适的组合器。
与克里斯迪福克相比,彼得的版本也比死锁安全得多!想象一下'request key'也会尝试访问同一个Cache。 –