packages feed

statethread (empty) → 0.1

raw patch · 9 files changed

+310/−0 lines, 9 filesdep +applicativedep +basedep +transformerssetup-changed

Dependencies added: applicative, base, transformers

Files

+ LICENSE view
@@ -0,0 +1,31 @@+Copyright (c) 2009, Henning Thielemann++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.++    * The names of contributors may not 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.lhs view
@@ -0,0 +1,3 @@+#! /usr/bin/env runhaskell+> import Distribution.Simple+> main = defaultMain
+ src/Control/Monad/ST.hs view
@@ -0,0 +1,3 @@+module Control.Monad.ST (module Control.Monad.ST.Strict) where++import Control.Monad.ST.Strict
+ src/Control/Monad/ST/Lazy.hs view
@@ -0,0 +1,113 @@+{-# LANGUAGE Rank2Types #-}+module Control.Monad.ST.Lazy (+   ST, runST, fixST,++   RealWorld, stToIO,++   strictToLazyST, lazyToStrictST,++   unsafeInterleaveST,+   unsafeIOToST+   ) where+++import qualified Control.Monad.ST.Strict as Strict+import Control.Monad.Trans.State (StateT(StateT), mapStateT, evalStateT, )+import Control.Monad.Trans (lift, )+import Control.Monad.Fix (MonadFix, mfix, )+import Control.Applicative (Applicative(pure, (<*>)), )+import System.IO.Unsafe (unsafePerformIO, unsafeInterleaveIO, )++++-- * The 'ST' Monad++{- |+The lazy state thread monad provides a weak form of sequencing:+If action A is written before B, then A will be run before B.+Generally an action is run whenever its result is needed+or when a subsequent action must be run.++This sequencing is necessary,+in order to run 'writeSTRef' actions at all+and run them in the right order and interleaving with 'readSTRef'.++I used the same idea in the @lazyio@ package.+-}+newtype ST s a = ST {unST :: StateT (State s) IO a}++data State s = State+++instance Functor (ST s) where+   fmap f (ST st) = ST (fmap f st)++instance Applicative (ST s) where+   pure f = ST (pure f)+   ST f <*> ST x = ST $+      mapStateT unsafeInterleaveIO f <*>+      mapStateT unsafeInterleaveIO x++instance Monad (ST s) where+   return f = ST (return f)+   fail str = ST (fail str)+   ST x >> ST y = ST $+      mapStateT unsafeInterleaveIO x >>+      mapStateT unsafeInterleaveIO y+   ST x >>= k = ST $+      mapStateT unsafeInterleaveIO . unST . k =<<+      mapStateT unsafeInterleaveIO x+++runST :: (forall s. ST s a) -> a+runST st = unsafePerformIO (evalStateT (unST st) State)++fixST :: (a -> ST s a) -> ST s a+fixST f = ST (mfix (unST . f))++instance MonadFix (ST s) where+   mfix = fixST+++-- * Converting 'ST' to 'IO'++data RealWorld = RealWorld++stToIO :: ST RealWorld a -> IO a+stToIO = flip evalStateT State . unST+++-- * Converting between strict and lazy 'ST'++strictToLazyST :: Strict.ST s a -> ST s a+strictToLazyST =+   unsafeIOToST . Strict.unsafeSTToIO++{-+ToDo:+Do we also have to bring the monadic result into some evaluated form?+Shall we also trigger all ST actions by a 'seq'ing on the final 'State'?+-}+lazyToStrictST :: ST s a -> Strict.ST s a+lazyToStrictST =+   Strict.unsafeIOToST . flip evalStateT State . unST+++-- * Unsafe operations++unsafeInterleaveST :: ST s a -> ST s a+unsafeInterleaveST (ST st) =+   ST $ StateT $ \_ -> fmap (\x->(x,State)) (evalStateT st State)++{-+Explicitly matching the @State@ constructor+forces former actions to be run.+-}+unsafeIOToST :: IO a -> ST s a+unsafeIOToST m =+   ST $ StateT $ \State -> fmap (\x->(x,State)) m++{-+unsafeSTToIO :: ST s a -> IO a+unsafeSTToIO = unST+-}
+ src/Control/Monad/ST/Strict.hs view
@@ -0,0 +1,64 @@+{-# LANGUAGE Rank2Types #-}+module Control.Monad.ST.Strict (+   ST, runST, fixST,++   RealWorld, stToIO,++   unsafeInterleaveST,+   unsafeIOToST,+   unsafeSTToIO,+   ) where++import Control.Monad.Fix (MonadFix, mfix, )+import Control.Applicative (Applicative(pure, (<*>)), )+import System.IO.Unsafe (unsafePerformIO, unsafeInterleaveIO, )+import System.IO (fixIO, )+++-- * The 'ST' Monad++newtype ST s a = ST {unST :: IO a}++instance Functor (ST s) where+   fmap f (ST st) = ST (fmap f st)++instance Applicative (ST s) where+   pure f = ST (pure f)+   ST f <*> ST x = ST (f <*> x)++instance Monad (ST s) where+   return f = ST (return f)+   fail str = ST (fail str)+   ST x >> ST y = ST (x >> y)+   ST x >>= k = ST (unST . k =<< x)+++runST :: (forall s. ST s a) -> a+runST st = unsafePerformIO (unST st)++fixST :: (a -> ST s a) -> ST s a+fixST f = ST (fixIO (unST . f))++instance MonadFix (ST s) where+   mfix = fixST+++-- * Converting 'ST' to 'IO'++data RealWorld = RealWorld++stToIO :: ST RealWorld a -> IO a+stToIO = unST+++-- * Unsafe operations++unsafeInterleaveST :: ST s a -> ST s a+unsafeInterleaveST (ST st) =+   ST (unsafeInterleaveIO st)++unsafeIOToST :: IO a -> ST s a+unsafeIOToST = ST++unsafeSTToIO :: ST s a -> IO a+unsafeSTToIO = unST
+ src/Data/STRef.hs view
@@ -0,0 +1,3 @@+module Data.STRef (module Data.STRef.Strict) where++import Data.STRef.Strict
+ src/Data/STRef/Lazy.hs view
@@ -0,0 +1,22 @@+module Data.STRef.Lazy (+   STRef,+   newSTRef,+   readSTRef,+   writeSTRef,+   modifySTRef,+   ) where++import Control.Monad.ST.Lazy (ST, strictToLazyST, )+import Data.STRef.Strict (STRef, )+import qualified Data.STRef.Strict as ST+++newSTRef    :: a -> ST s (STRef s a)+readSTRef   :: STRef s a -> ST s a+writeSTRef  :: STRef s a -> a -> ST s ()+modifySTRef :: STRef s a -> (a -> a) -> ST s ()++newSTRef   = strictToLazyST . ST.newSTRef+readSTRef  = strictToLazyST . ST.readSTRef+writeSTRef r a = strictToLazyST (ST.writeSTRef r a)+modifySTRef r f = strictToLazyST (ST.modifySTRef r f)
+ src/Data/STRef/Strict.hs view
@@ -0,0 +1,31 @@+module Data.STRef.Strict (+   STRef,+   newSTRef,+   readSTRef,+   writeSTRef,+   modifySTRef,+   ) where++import Control.Monad.ST.Strict (ST, )+import qualified Control.Monad.ST.Strict as Strict+import qualified Data.IORef as IORef+++newtype STRef s a = STRef {unSTRef :: IORef.IORef a}+++newSTRef :: a -> ST s (STRef s a)+newSTRef a =+   Strict.unsafeIOToST (fmap STRef (IORef.newIORef a))++readSTRef :: STRef s a -> ST s a+readSTRef ref =+   Strict.unsafeIOToST (IORef.readIORef (unSTRef ref))++writeSTRef :: STRef s a -> a -> ST s ()+writeSTRef ref a =+   Strict.unsafeIOToST (IORef.writeIORef (unSTRef ref) a)++modifySTRef :: STRef s a -> (a -> a) -> ST s ()+modifySTRef ref f =+   Strict.unsafeIOToST (IORef.modifyIORef (unSTRef ref) f)
+ statethread.cabal view
@@ -0,0 +1,40 @@+Name:           statethread+Version:        0.1+License:        BSD3+License-File:   LICENSE+Maintainer:     haskell@henning-thielemann.de+Synopsis:       The ST monad and STRefs+Category:       Data Structures, Monads+Description:+  The ST monad and STRefs in a portable form.+  This package implements state threads as wrapper around IO and IORefs.+  Your compiler must support rank-2-types, IORefs,+  unsafePerformIO and unsafeInterleaveIO.+  The package can be used as drop-in replacement for the 'st' package.+Build-Type:     Simple+Cabal-Version:  >=1.6+Tested-With:    JHC==0.7.3++Source-Repository this+  Tag:         0.1+  Type:        darcs+  Location:    http://darcs.haskell.org/packages/statethread/++Source-Repository head+  Type:        darcs+  Location:    http://darcs.haskell.org/packages/statethread/++Library+  Build-Depends:+    transformers >=0.0 && <0.2,+    applicative >=1.0 && <1.1,+    base >=1.0 && <2+  Extensions: Rank2Types+  Hs-Source-Dirs: src+  Exposed-Modules:+    Control.Monad.ST+    Control.Monad.ST.Lazy+    Control.Monad.ST.Strict+    Data.STRef+    Data.STRef.Lazy+    Data.STRef.Strict