Polysemy: Interpretation and effects inline injectionGautier DI FOLCO December 18, 2022 [Haskell] #haskell #polysemy #design #effects systems
In a previous log we have seen a way to cache computation and a way to inject effects.
Let see what it take to build a caching effect:
data Cache k v (m :: Type -> Type) a where Cached :: k -> Cache k v m v
As opposed to
View, we have a cache per key and not a global cache, it could lead to memory leaks.
We can use it as follows:
= do name0 <- cached "name" embed $ putStrLn $ "Your name is " <> name0 location0 <- cached "location" embed $ putStrLn $ "Your location is " <> location0 name1 <- cached "name" location1 <- cached "location" embed $ putStrLn $ "Hello " <> name1 <> " from " <> location1 app
It let use with the interpreter:
= evalState mempty . interpret (\case Cached k -> do currentCache <- get @(M.Map k v) case currentCache M.!? k of Nothing -> do v <- raise $ f k put $ M.insert k v currentCache return v Just v -> return v ) . raiseUnder @(State (M.Map k v)) runCache f
It can be understood this way:
- Add a new effect with
raiseUnder(so we have
(State (M.Map k v) ': r))
- Get current cache
- Run the computation when key is missing (here we are forced to use
- Run the
Finally, here's what it gives:
What's your name? Gautier Your name is Gautier What's your location? France Your location is France Hello Gautier from France
See the full the code here.