packages feed

vault (empty) → 0.1.0.0

raw patch · 6 files changed

+233/−0 lines, 6 filesdep +basedep +containerssetup-changed

Dependencies added: base, containers

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c)2011, Heinrich Apfelmus++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Heinrich Apfelmus nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Readme.md view
@@ -0,0 +1,44 @@+*Vault* is a tiny library that provides a single data structure called *vault*.++A *vault* is a type-safe, persistent storage for values of arbitrary types. Like `IORef`, I want to be able to store values of any type in it, but unlike `IORef`, I want the storage space to behave like a persistent, first-class data structure, as appropriate for a purely functional language.++It is analogous to a bank vault, where you can access different bank boxes with different keys; hence the name.++In other words, a vault is an abstract data type with the following basic signature++    data Key a+    data Vault++    newKey :: IO (Key a)+    empty  :: Vault+    lookup :: Key a -> Vault -> Maybe a+    insert :: Key a -> a -> Vault -> Vault+    delete :: Key a -> Vault -> Vault++A few common functions for finite maps, like `adjust` and `union`, are provided as well.+++This library was created thanks to the feedback on my blog post [Vault - a persistent store for values of arbitrary types][1].++  [1]: http://apfelmus.nfshost.com/blog/2011/09/04-vault.html+++Installation+============+The whole thing is [available on hackage][hackage], so you just have to type++    cabal update+    cabal install vault++  [hackage]: http://hackage.haskell.org/package/vault++Feedback+========+Use the [issue tracker][2] or send an [email to the maintainer][3].++  [2]: https://github.com/HeinrichApfelmus/vault/issues+  [3]: mailto:apfelmus@quantentunnel.de++++
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Data/Vault.hs view
@@ -0,0 +1,57 @@+{-----------------------------------------------------------------------------+    Vault+    +    A typed, persistent store for values of arbitrary types+    +    This implementation uses  unsafeCoerce  for reasons of efficiency.+    See  http://apfelmus.nfshost.com/blog/2011/09/04-vault.html+    for an implementation that doesn't need to bypass the type checker.+------------------------------------------------------------------------------}+module Data.Vault (+    Vault, Key,+    empty, newKey, lookup, insert, adjust, delete, union,+    ) where++import Prelude hiding (lookup)+import Control.Monad.ST+import qualified Data.Vault.ST as ST++-- | A typed, persistent store for values of arbitrary types.+-- +-- This variant is the simplest and creates keys in the 'IO' monad.+-- See the module "Data.Vault.ST" if you want to use it with the 'ST' monad instead.+--+-- > instance Monoid Vault+type Vault = ST.Vault RealWorld+-- | Keys for the vault.+--+-- > Key :: * -> *+type Key = ST.Key RealWorld++-- | The empty vault.+empty :: Vault+empty = ST.empty++-- | Create a new key for use with a vault.+newKey :: IO (Key a)+newKey = stToIO ST.newKey++-- | Lookup the value of a key in the vault.+lookup :: Key a -> Vault -> Maybe a+lookup = ST.lookup++-- | Insert a value for a given key. Overwrites any previous value.+insert :: Key a -> a -> Vault -> Vault+insert = ST.insert++-- | Adjust the value for a given key if it's present in the vault.+adjust :: (a -> a) -> Key a -> Vault -> Vault+adjust = ST.adjust++-- | Delete a key from the vault.+delete :: Key a -> Vault -> Vault+delete = ST.delete++-- | Merge two vaults (left-biased).+union :: Vault -> Vault -> Vault+union = ST.union
+ src/Data/Vault/ST.hs view
@@ -0,0 +1,66 @@+{-----------------------------------------------------------------------------+    Vault+    +    A typed, persistent store for values of arbitrary types+    +    This implementation uses  unsafeCoerce  for reasons of efficiency.+    See  http://apfelmus.nfshost.com/blog/2011/09/04-vault.html+    for an implementation that doesn't need to bypass the type checker.+------------------------------------------------------------------------------}+module Data.Vault.ST (+    Vault, Key,+    empty, newKey, lookup, insert, adjust, delete, union,+    ) where++import Prelude hiding (lookup)+import Data.Monoid hiding (Any)+import Data.Functor+import Data.Map (Map)+import qualified Data.Map as Map+import Data.Unique+import Control.Monad.ST++import GHC.Exts (Any)   -- ghc specific tricks+import Unsafe.Coerce (unsafeCoerce)++-- | A typed, persistent store for values of arbitrary types.+-- +-- This variant has more complex types so that you can create keys in the 'ST' monad.+-- See the module "Data.Vault" if you'd like to use a simpler version with the 'IO' monad.+-- You can also use both variants simultaneously; they share a single representation.+newtype Vault s = Vault (Map Unique Any)+-- | Keys for the vault.+newtype Key s a = Key Unique++instance Monoid (Vault s) where+    mempty = empty+    mappend = union++-- | The empty vault.+empty :: Vault s+empty = Vault Map.empty++-- | Create a new key for use with a vault.+newKey :: ST s (Key s a)+newKey = Key <$> unsafeIOToST newUnique++-- | Lookup the value of a key in the vault.+lookup :: Key s a -> Vault s -> Maybe a+lookup (Key k) (Vault m) = unsafeCoerce <$> Map.lookup k m ++-- | Insert a value for a given key. Overwrites any previous value.+insert :: Key s a -> a -> Vault s -> Vault s+insert (Key k) x (Vault m) = Vault $ Map.insert k (unsafeCoerce x) m++-- | Adjust the value for a given key if it's present in the vault.+adjust :: (a -> a) -> Key s a -> Vault s -> Vault s+adjust f (Key k) (Vault m) = Vault $ Map.alter f' k m+    where f' = unsafeCoerce . f . unsafeCoerce++-- | Delete a key from the vault.+delete :: Key s a -> Vault s -> Vault s+delete (Key k) (Vault m) = Vault $ Map.delete k m++-- | Merge two vaults (left-biased).+union :: Vault s -> Vault s -> Vault s+union (Vault m) (Vault m') = Vault $ Map.union m m'
+ vault.cabal view
@@ -0,0 +1,34 @@+Name:               vault+Version:            0.1.0.0+Synopsis:           a typed, persistent store for values of arbitrary types+Description:+  A /vault/ is a typed, persistent store for values of arbitrary types.+  It's like having first-class access to the storage space behind IORefs.+  .+  The data structure is analogous to a bank vault,+  where you can access different bank boxes with different keys;+  hence the name.+  +Category:           Data+License:            BSD3+License-file:       LICENSE+Author:             Heinrich Apfelmus, Elliott Hird+Maintainer:         Heinrich Apfelmus <apfelmus at quantentunnel de>+Homepage:           https://github.com/HeinrichApfelmus/vault+Copyright:          (c) Heinrich Apfelmus 2011++build-type:         Simple+cabal-version:      >= 1.6++extra-source-files: Readme.md++source-repository head+    type:           git+    location:       git://github.com/HeinrichApfelmus/vault.git++Library+    hs-source-dirs:     src+    build-depends:      base == 4.*, containers == 0.4.*+    ghc-options:        -Wall+    exposed-modules:    Data.Vault, Data.Vault.ST+