value-supply 0.2 → 0.3
raw patch · 2 files changed
+47/−21 lines, 2 files
Files
- Data/Supply.hs +46/−20
- value-supply.cabal +1/−1
Data/Supply.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} -------------------------------------------------------------------- -- | -- Module : Data.Supply@@ -35,8 +36,15 @@ ) where -- Usinga an IORef is thread-safe because we update it with 'atomicModifyIORef'.-import Data.IORef+import Data.IORef(IORef,newIORef,atomicModifyIORef)++#if __GLASGOW_HASKELL__ >= 608+import GHC.IOBase(unsafeDupableInterleaveIO)+#else import System.IO.Unsafe(unsafeInterleaveIO)+unsafeDupableInterleaveIO :: IO a -> IO a+unsafeDupableInterleaveIO = unsafeInterleaveIO+#endif -- Basics ---------------------------------------------------------------------- @@ -60,21 +68,49 @@ instance Functor Supply where fmap f s = modifySupply s (f . supplyValue) ++{-# 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+ rs <- gen r+ return (Node v ls rs)+ -- | Creates a new supply of values. -- The arguments specify how to generate values: -- the first argument is an initial value, the -- second specifies how to generate a new value from an existing one.-newSupply :: a -> (a -> a) -> IO (Supply a)-newSupply x f = gen =<< newIORef (iterate f x)+newSupply :: a -> (a -> a) -> IO (Supply a)+newSupply x f = genericNewSupply (iterate f x) listGenSym - where gen r = do v <- unsafeInterleaveIO (genSym r)- ls <- unsafeInterleaveIO (gen r)- rs <- unsafeInterleaveIO (gen r)- return (Node v ls rs)+{-# SPECIALIZE newEnumSupply :: IO (Supply Int) #-}+-- | A supply of values that are in the 'Enum' class.+-- The initial value is @toEnum 0@, new values are generates with 'succ'.+newEnumSupply :: (Enum a) => IO (Supply a)+newEnumSupply = genericNewSupply (toEnum 0) enumGenSym - genSym :: IORef [a] -> IO a- genSym r = atomicModifyIORef r (\(a:as) -> (as,a))- +{-# SPECIALIZE newNumSupply :: IO (Supply Int) #-}+-- | A supply of values that are in the 'Num' class.+-- The initial value is 0, new values are generated by adding 1.+newNumSupply :: (Num a) => IO (Supply a)+newNumSupply = genericNewSupply 0 numGenSym+++-- Different ways to generate new values:+listGenSym :: IORef [a] -> IO a+listGenSym r = atomicModifyIORef r (\(a:as) -> (as,a))++enumGenSym :: Enum a => IORef a -> IO a+enumGenSym r = atomicModifyIORef r (\a -> let n = succ a in seq n (n,a))++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 -- to an existing supply. This function, together with 'supplyValue' -- form a comonad on 'Supply'.@@ -95,16 +131,6 @@ -- Derived functions --------------------------------------------------------------- | A supply of values that are in the 'Enum' class.--- The initial value is @toEnum 0@, new values are generates with 'succ'.-newEnumSupply :: (Enum a) => IO (Supply a)-newEnumSupply = newSupply (toEnum 0) succ---- | A supply of values that are in the 'Num' class.--- The initial value is 0, new values are generated by adding 1.-newNumSupply :: (Num a) => IO (Supply a)-newNumSupply = newSupply 0 (1+) -- | Generate an infinite list of supplies by using 'supplyLeft' and -- 'supplyRight' repeatedly.
value-supply.cabal view
@@ -1,5 +1,5 @@ Name: value-supply-Version: 0.2+Version: 0.3 License: BSD3 License-file: LICENSE Author: Iavor S. Diatchki