gdritter repos tansu / b0643c4
Reflected key/value types into Tansu monad type Getty Ritter 8 years ago
2 changed file(s) with 20 addition(s) and 20 deletion(s). Collapse all Expand all
3131 -- make some guarantee about the atomicity of a given
3232 -- 'Tansu' computation, but you should consult the documentation
3333 -- about a given backend to make sure that holds.
34 newtype Tansu a = Tansu { runTansu :: TansuM a }
34 newtype Tansu k v a = Tansu { runTansu :: TansuM a }
3535
36 instance Functor Tansu where
36 instance Functor (Tansu k v) where
3737 fmap f (Tansu t) = Tansu (fmap f t)
3838
39 instance Applicative Tansu where
39 instance Applicative (Tansu k v) where
4040 pure = Tansu . pure
4141 Tansu f <*> Tansu x = Tansu (f <*> x)
4242
43 instance Monad Tansu where
43 instance Monad (Tansu k v) where
4444 Tansu x >>= f = Tansu (x >>= runTansu . f)
4545
4646 -- | Sets the value for a key to a value.
47 set :: (Serialize k, Serialize v) => k -> v -> Tansu ()
47 set :: (Serialize k, Serialize v) => k -> v -> Tansu k v ()
4848 set key val = do
4949 db <- Tansu ask
5050 Tansu $ inBase $ dbSet db (encode key) (encode val)
5151
5252 -- | Sets the value for a key to a value. A convenience operator
5353 -- that is identical to 'set'.
54 (=:) :: (Serialize k, Serialize v) => k -> v -> Tansu ()
54 (=:) :: (Serialize k, Serialize v) => k -> v -> Tansu k v ()
5555 (=:) = set
5656
5757 -- | Gets a value for a given key. The resulting 'Tansu' computation
5858 -- will fail if the key is not present in the storage backend.
59 get :: (Serialize k, Serialize v) => k -> Tansu v
59 get :: (Serialize k, Serialize v) => k -> Tansu k v v
6060 get key = do
6161 result <- getMb key
6262 case result of
6868 -- as problems decoding the serialized value or difficulties
6969 -- communicating with the storage backend, will still cause the
7070 -- 'Tansu' computation to fail.
71 getMb :: (Serialize k, Serialize v) => k -> Tansu (Maybe v)
71 getMb :: (Serialize k, Serialize v) => k -> Tansu k v (Maybe v)
7272 getMb key = do
7373 db <- Tansu ask
7474 result <- Tansu $ inBase $ dbGet db (encode key)
7878 Right val' -> return (Just val')
7979 Left err -> Tansu (raise (DecodeError err))
8080
81 del :: (Serialize k) => k -> Tansu ()
81 del :: (Serialize k) => k -> Tansu k v ()
8282 del key = do
8383 db <- Tansu ask
8484 Tansu $ inBase $ dbDel db (encode key)
8686 -- | Given a storage backend and a 'Tansu' computation, execute the
8787 -- sequence of 'get' and 'set' commands and produce either the value
8888 -- or the error encountered while running the computation.
89 run :: TansuDb -> Tansu a -> IO (Either TansuError a)
89 run :: TansuDb -> Tansu k v a -> IO (Either TansuError a)
9090 run db (Tansu comp) =
9191 dbRunTransaction db (runExceptionT (runReaderT db comp))
2828 main :: IO ()
2929 main = withFilesystemDb "sample.db" $ \ db -> do
3030 run db $ do
31 "alex" =: Person "alex" 33
32 "blake" =: Person "blake" 22
31 "alex" =: Person "Alex" 33
32 "blake" =: Person "Blake" 22
3333
3434 Right age <- run db (age `fmap` get "blake")
3535 putStrLn $ "Blake's age is " ++ show age
4141 the `Serialize` typeclass from the
4242 [`cereal`](https://hackage.haskell.org/package/cereal)
4343 library. No type information is saved in the key-value store, so care must
44 be taken to ensure that the correct deserializer is being used when a value
45 is extracted from the backing store.
44 be taken to ensure that the correct types are used in creating a `Tansu`
45 computation.
4646
4747 A value of type `TansuDb` represents a given key-value mapping. The only
4848 way to interact with a `TansuDb` is by running a `Tansu` command, which
5353
5454 ~~~.haskell
5555 -- set a key to a value
56 set :: (Serialize k, Serialize v) => k -> v -> Tansu ()
56 set :: (Serialize k, Serialize v) => k -> v -> Tansu k v ()
5757
5858 -- infix alias for set
59 (=:) :: (Serialize k, Serialize v) => k -> v -> Tansu ()
59 (=:) :: (Serialize k, Serialize v) => k -> v -> Tansu k v ()
6060
6161 -- get a value, failing if it does not exist
62 get :: (Serialize k, Serialize v) => k -> Tansu v
62 get :: (Serialize k, Serialize v) => k -> Tansu k v v
6363
6464 -- get a value, returning Nothing if it does not exist
65 getMb :: (Serialize k, Serialize v) => k -> Tansu (Maybe v)
65 getMb :: (Serialize k, Serialize v) => k -> Tansu k v (Maybe v)
6666
6767 -- remove a key and its associated value
68 del :: (Serialize k) => k -> Tansu ()
68 del :: (Serialize k) => k -> Tansu k v ()
6969
7070 -- run a Tansu computation
71 run :: TansuDb -> Tansu a -> IO (Either TansuError a)
71 run :: TansuDb -> Tansu k v a -> IO (Either TansuError a)
7272 ~~~
7373
7474 A value of type `TansuDb` should be supplied by a _backend_, which can