packages feed

value-supply 0.2 → 0.3

raw patch · 2 files changed

+47/−21 lines, 2 files

Files

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