packages feed

StateVar (empty) → 1.0.0.0

raw patch · 4 files changed

+192/−0 lines, 4 filesdep +basesetup-changed

Dependencies added: base

Files

+ 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