persistent-refs (empty) → 0.1
raw patch · 6 files changed
+203/−0 lines, 6 filesdep +basedep +containersdep +lenssetup-changed
Dependencies added: base, containers, lens, mtl, ref-fd, transformers
Files
- LICENSE +30/−0
- Setup.hs +2/−0
- persistent-refs.cabal +36/−0
- src/Control/Monad/ST/Persistent.hs +26/−0
- src/Control/Monad/ST/Persistent/Internal.hs +49/−0
- src/Data/STRef/Persistent.hs +60/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2013, Adam C. Foltzer++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 Adam C. Foltzer 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.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ persistent-refs.cabal view
@@ -0,0 +1,36 @@+name: persistent-refs+version: 0.1+license: BSD3+license-file: LICENSE+author: Adam C. Foltzer+maintainer: acfoltzer@gmail.com+homepage: https://github.com/acfoltzer/persistent-refs+bug-reports: https://github.com/acfoltzer/persistent-refs/issues+category: Data+build-type: Simple+cabal-version: >=1.8+synopsis: + Haskell references backed by an IntMap for persistence and reversibility.+description:+ This library provides support for a persistent version of the+ 'Control.Monad.ST.ST' monad. Internally, references are backed by a+ 'Data.IntMap.IntMap', rather than being mutable variables on the+ heap. This decreases performance, but can be useful in certain+ settings, particularly those involving backtracking.++source-repository head+ type: git+ location: git://github.com/acfoltzer/persistent-refs.git++library+ build-depends: base >= 4.0 && < 5,+ containers >= 0.4 && < 0.6,+ lens >= 3.7 && < 3.9,+ mtl >= 2.1 && < 2.2,+ ref-fd >= 0.3 && < 0.4,+ transformers >= 0.3 && < 0.4+ exposed-modules: Control.Monad.ST.Persistent,+ Data.STRef.Persistent+ other-modules: Control.Monad.ST.Persistent.Internal+ hs-source-dirs: src+ ghc-options: -Wall
+ src/Control/Monad/ST/Persistent.hs view
@@ -0,0 +1,26 @@+-----------------------------------------------------------------------------+-- |+-- Module : Control.Monad.ST.Persistent+-- Copyright : (c) Adam C. Foltzer 2013+-- License : BSD3+--+-- Maintainer : acfoltzer@gmail.com+-- Stability : experimental+-- Portability : non-portable (requires rank-2 types for runST)+--+-- This library provides support for a persistent version of the+-- 'Control.Monad.ST.ST' monad. Internally, references are backed by a+-- 'Data.IntMap.IntMap', rather than being mutable variables on the+-- heap. This decreases performance, but can be useful in certain+-- settings, particularly those involving backtracking.+--+-----------------------------------------------------------------------------++module Control.Monad.ST.Persistent (+ -- * The Persistent 'ST' Monad+ ST+ , runST+ ) where++import Control.Monad.ST.Persistent.Internal+
+ src/Control/Monad/ST/Persistent/Internal.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE TemplateHaskell #-}++{-# OPTIONS_GHC -ddump-splices #-}+module Control.Monad.ST.Persistent.Internal where++import Control.Applicative (Applicative)+import Control.Lens+import Control.Monad.State.Strict+import Data.IntMap+import GHC.Base++data Heap = Heap { _heap :: IntMap Any, _next :: Int }+-- makeLenses ''Heap++-- manually using splices because TH before 7.6 can't handle Any+heap :: Lens' Heap (IntMap Any)+heap _f_a1T2 (Heap __heap'_a1T3 __next_a1T5)+ = ((\ __heap_a1T4 -> Heap __heap_a1T4 __next_a1T5)+ `fmap` (_f_a1T2 __heap'_a1T3))+{-# INLINE heap #-}+next :: Lens' Heap Int+next _f_a1T6 (Heap __heap_a1T7 __next'_a1T8)+ = ((\ __next_a1T9 -> Heap __heap_a1T7 __next_a1T9)+ `fmap` (_f_a1T6 __next'_a1T8))+{-# INLINE next #-}++emptyHeap :: Heap+emptyHeap = Heap { _heap = empty, _next = minBound }++-- | A persistent version of the 'Control.Monad.ST.ST' monad.+newtype ST s a = ST (State Heap a)+ deriving (Functor, Applicative, Monad)++-- | Run a computation that uses persistent references, and return a+-- pure value. The rank-2 type offers similar guarantees to+-- 'Control.Monad.ST.runST'.+runST :: (forall s. ST s a) -> a+runST (ST c) = evalState c emptyHeap++-- I'm not sure whether the semantics of this transformer actually+-- make any sense, so I'm not exporting this for now...++newtype STT s m a = STT (StateT Heap m a)+ deriving (Functor, Applicative, Monad, MonadIO)++runSTT :: Monad m => (forall s. STT s m a) -> m a+runSTT (STT c) = evalStateT c emptyHeap
+ src/Data/STRef/Persistent.hs view
@@ -0,0 +1,60 @@+{-# LANGUAGE MultiParamTypeClasses #-}++{-# OPTIONS_GHC -fno-warn-orphans #-}++-----------------------------------------------------------------------------+-- |+-- Module : Data.STRef.Persistent+-- Copyright : (c) Adam C. Foltzer 2013+-- License : BSD3+--+-- Maintainer : acfoltzer@gmail.com+-- Stability : experimental+-- Portability : non-portable (requires rank-2 types for runST)+--+-- Mutable references in the persistent+-- 'Control.Monad.ST.Persistent.ST' monad.+--+-----------------------------------------------------------------------------++module Data.STRef.Persistent (+ -- * 'STRef's+ STRef+ -- * 'MonadRef' Operations+ , MonadRef(..)+ , modifyRef'+ ) where++import Control.Lens+import Control.Monad.Ref+import Control.Monad.ST.Persistent.Internal+import Data.IntMap as IntMap+import Data.Maybe+import Unsafe.Coerce++newtype STRef s a = STRef Int++newSTRef :: a -> ST s (STRef s a)+newSTRef x = ST $ do + i <- next <<%= (+1)+ heap %= insert i (unsafeCoerce x)+ return (STRef i)++readSTRef :: STRef s a -> ST s a+readSTRef (STRef i) = + ST $ uses heap (unsafeCoerce . fromJust . IntMap.lookup i)++writeSTRef :: STRef s a -> a -> ST s ()+writeSTRef (STRef i) x = + ST $ heap %= insert i (unsafeCoerce x)++instance MonadRef (STRef s) (ST s) where+ newRef = newSTRef+ readRef = readSTRef+ writeRef = writeSTRef++modifyRef' :: MonadRef r m => r a -> (a -> a) -> m ()+modifyRef' r f = do+ x <- readRef r+ let x' = f x+ x' `seq` writeRef r x'