StateVar (empty) → 1.0.0.0
raw patch · 4 files changed
+192/−0 lines, 4 filesdep +basesetup-changed
Dependencies added: base
Files
- LICENSE +28/−0
- Setup.hs +2/−0
- StateVar.cabal +17/−0
- src/Data/StateVar.hs +145/−0
+ LICENSE view
@@ -0,0 +1,28 @@+Copyright (c) 2009, Sven Panne+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++1. Redistributions of source code must retain the above copyright notice,+ this list of conditions and the following disclaimer.++2. 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.++3. Neither the name of the author nor the names of its 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
+ StateVar.cabal view
@@ -0,0 +1,17 @@+name: StateVar+version: 1.0.0.0+license: BSD3+license-file: LICENSE+maintainer: Sven Panne <sven.panne@aedion.de>+bug-reports: mailto:hopengl@haskell.org+homepage: http://www.haskell.org/HOpenGL/+category: Data+synopsis: State variables+description:+ This package contains state variables, which are references in the IO monad,+ like IORefs or parts of the OpenGL state.+build-type: Simple+exposed-modules: Data.StateVar+hs-Source-Dirs: src+ghc-options: -Wall+build-depends: base >= 3 && < 5
+ src/Data/StateVar.hs view
@@ -0,0 +1,145 @@+--------------------------------------------------------------------------------+-- |+-- Module : Data.StateVar+-- Copyright : (c) Sven Panne 2009+-- License : BSD-style (see the file LICENSE)+-- +-- Maintainer : sven.panne@aedion.de+-- Stability : stable+-- Portability : portable+--+-- State variables are references in the IO monad, like 'IORef's or parts of+-- the OpenGL state. Note that state variables are not neccessarily writable or+-- readable, they may come in read-only or write-only flavours, too. As a very+-- simple example for a state variable, consider an explicitly allocated memory+-- buffer. This buffer can easily be converted into a 'StateVar':+--+-- @+-- makeStateVarFromPtr :: Storable a => Ptr a -> StateVar a+-- makeStateVarFromPtr p = makeStateVar (peek p) (poke p)+-- @+--+-- The example below puts 11 into a state variable (i.e. into the buffer),+-- increments the contents of the state variable by 22, and finally prints the+-- resulting content:+--+-- @+-- do p <- malloc :: IO (Ptr Int)+-- let v = makeStateVarFromPtr p+-- v $= 11+-- v $~ (+ 22)+-- x <- get v+-- print x+-- @+--+-- 'IORef's are state variables, too, so an example with them looks extremely+-- similiar:+--+-- @+-- do v <- newIORef (0 :: Int)+-- v $= 11+-- v $~ (+ 22)+-- x <- get v+-- print x+-- @+--------------------------------------------------------------------------------++module Data.StateVar (+ -- * Readable State Variables+ HasGetter(..),+ GettableStateVar, makeGettableStateVar,+ -- * Writable State Variables+ HasSetter(..),+ SettableStateVar, makeSettableStateVar,+ -- * General State Variables+ StateVar, makeStateVar,+ -- * Utility Functions+ ($~), ($=!), ($~!)+) where++import Data.IORef ( IORef, readIORef, writeIORef )++--------------------------------------------------------------------------------++infixr 2 $=++--------------------------------------------------------------------------------++-- | The class of all readable state variables.+class HasGetter g where+ -- | Read the value of a state variable.+ get :: g a -> IO a++instance HasGetter IORef where+ get = readIORef++-- | A concrete implementation of a read-only state variable, carrying an IO+-- action to read the value.+newtype GettableStateVar a = GettableStateVar (IO a)++instance HasGetter GettableStateVar where+ get (GettableStateVar g) = g++-- | Construct a 'GettableStateVar' from an IO action.+makeGettableStateVar :: IO a -> GettableStateVar a+makeGettableStateVar = GettableStateVar++--------------------------------------------------------------------------------++-- | The class of all writable state variables.+class HasSetter s where+ -- | Write a new value into a state variable.+ ($=) :: s a -> a -> IO ()++instance HasSetter IORef where+ ($=) = writeIORef++-- | A concrete implementation of a write-only state variable, carrying an IO+-- action to write the new value.+newtype SettableStateVar a = SettableStateVar (a -> IO ())++instance HasSetter SettableStateVar where+ ($=) (SettableStateVar s) a = s a++-- | Construct a 'SettableStateVar' from an IO action.+makeSettableStateVar :: (a -> IO ()) -> SettableStateVar a+makeSettableStateVar = SettableStateVar++--------------------------------------------------------------------------------++-- | A concrete implementation of a readable and writable state variable,+-- carrying one IO action to read the value and another IO action to write the+-- new value.+data StateVar a =+ StateVar (GettableStateVar a) (SettableStateVar a)++instance HasGetter StateVar where+ get (StateVar g _) = get g++instance HasSetter StateVar where+ ($=) (StateVar _ s) a = s $= a++-- | Construct a 'StateVar' from two IO actions, one for reading and one for+-- writing.+makeStateVar :: IO a -> (a -> IO ()) -> StateVar a+makeStateVar g s = StateVar (makeGettableStateVar g) (makeSettableStateVar s)++--------------------------------------------------------------------------------++-- | A modificator convenience function, transforming the contents of a state+-- variable with a given funtion.++($~) :: (HasGetter v, HasSetter v) => v a -> (a -> a) -> IO ()+v $~ f = do+ x <- get v+ v $= f x++-- | A variant of '$=' which is strict in the value to be set.+($=!) :: HasSetter s => s a -> a -> IO ()+v $=! x = x `seq` v $= x++-- | A variant of '$~' which is strict in the transformed value.+($~!) :: (HasGetter v, HasSetter v) => v a -> (a -> a) -> IO ()+v $~! f = do+ x <- get v+ v $=! f x