value-supply 0.3 → 0.4
raw patch · 2 files changed
+25/−9 lines, 2 files
Files
- Data/Supply.hs +24/−8
- value-supply.cabal +1/−1
Data/Supply.hs view
@@ -21,6 +21,7 @@ , newSupply , newEnumSupply , newNumSupply+ , unsafeNewIntSupply -- * Obtaining values from supplies , supplyValue@@ -36,14 +37,18 @@ ) where -- Usinga an IORef is thread-safe because we update it with 'atomicModifyIORef'.+-- XXX: Is the atomic necessary? import Data.IORef(IORef,newIORef,atomicModifyIORef)+import System.IO.Unsafe(unsafePerformIO,unsafeInterleaveIO) #if __GLASGOW_HASKELL__ >= 608-import GHC.IOBase(unsafeDupableInterleaveIO)+import GHC.IOBase(unsafeDupableInterleaveIO,unsafeDupablePerformIO) #else-import System.IO.Unsafe(unsafeInterleaveIO) unsafeDupableInterleaveIO :: IO a -> IO a unsafeDupableInterleaveIO = unsafeInterleaveIO++unsafeDupablePerformIO :: IO a -> a+unsafeDupablePerformIO = unsafePerformIO #endif -- Basics ----------------------------------------------------------------------@@ -72,12 +77,10 @@ {-# INLINE genericNewSupply #-} genericNewSupply :: b -> (IORef b -> IO a) -> IO (Supply a) genericNewSupply start genSym = gen =<< newIORef start-- where gen r = unsafeDupableInterleaveIO- $ do v <- unsafeDupableInterleaveIO (genSym r)- ls <- gen r+ where gen r = unsafeInterleaveIO+ $ do ls <- gen r rs <- gen r- return (Node v ls rs)+ return (Node (unsafePerformIO (genSym r)) ls rs) -- | Creates a new supply of values. -- The arguments specify how to generate values:@@ -98,7 +101,21 @@ newNumSupply :: (Num a) => IO (Supply a) newNumSupply = genericNewSupply 0 numGenSym +-- | Create a supply of ints.+-- WARNING: In general, this is not thread safe!+-- It should be OK, as long as the supply is not accessed by different threads.+-- So, if you are in a multi-threaded setting, first split+-- the supply, and give /different/ supply values to the different threads.+unsafeNewIntSupply :: IO (Supply Int)+unsafeNewIntSupply = gen =<< newIORef 0+ where gen r = unsafeDupableInterleaveIO+ $ do ls <- gen r+ rs <- gen r+ return (Node (unsafeDupablePerformIO (enumGenSym r)) ls rs) +++ -- Different ways to generate new values: listGenSym :: IORef [a] -> IO a listGenSym r = atomicModifyIORef r (\(a:as) -> (as,a))@@ -108,7 +125,6 @@ numGenSym :: Num a => IORef a -> IO a numGenSym r = atomicModifyIORef r (\a -> let n = 1 + a in seq n (n,a))- -- | Generate a new supply by systematically applying a function
value-supply.cabal view
@@ -1,5 +1,5 @@ Name: value-supply-Version: 0.3+Version: 0.4 License: BSD3 License-file: LICENSE Author: Iavor S. Diatchki