module Kv where import Control.Monad import Data.Either import Data.HashMap.Strict as Map import Data.Hashable (Hashable) import Data.Maybe import Polysemy import Polysemy.AtomicState data KVStore k v m a where Kvset :: k -> v -> KVStore k v m () Kvget :: k -> KVStore k v m (Maybe v) Kvdel :: k -> KVStore k v m () makeSem ''KVStore -- template haskell -- we use atomic operations to be thread safe in concurrency runKVStoreAtomic :: ( Member (AtomicState (HashMap k v)) r, Eq k, Hashable k ) => Sem (KVStore k v ': r) a -> Sem r a runKVStoreAtomic = interpret $ \case Kvset k v -> atomicModify' $ Map.insert k v Kvget k -> atomicGets $ Map.lookup k Kvdel k -> atomicModify' $ Map.delete k kvgets :: (Member (KVStore k v) r, Eq k, Hashable k) => (v -> a) -> k -> Sem r (Maybe a) kvgets f k = fmap f <$> kvget k