Hello community,

here is the log from the commit of package ghc-StateVar for openSUSE:Factory 
checked in at 2015-08-10 09:16:48
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-StateVar (Old)
 and      /work/SRC/openSUSE:Factory/.ghc-StateVar.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ghc-StateVar"

Changes:
--------
--- /work/SRC/openSUSE:Factory/ghc-StateVar/ghc-StateVar.changes        
2015-05-21 08:14:15.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.ghc-StateVar.new/ghc-StateVar.changes   
2015-08-10 09:16:50.000000000 +0200
@@ -1,0 +2,5 @@
+Thu Aug  6 18:36:25 UTC 2015 - mimi...@gmail.com
+
+- update to 1.1.0.1
+
+-------------------------------------------------------------------

Old:
----
  StateVar-1.1.0.0.tar.gz

New:
----
  StateVar-1.1.0.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ghc-StateVar.spec ++++++
--- /var/tmp/diff_new_pack.d1QWFl/_old  2015-08-10 09:16:51.000000000 +0200
+++ /var/tmp/diff_new_pack.d1QWFl/_new  2015-08-10 09:16:51.000000000 +0200
@@ -17,8 +17,8 @@
 
 %global pkg_name StateVar
 
-Name:           ghc-%{pkg_name}
-Version:        1.1.0.0
+Name:           ghc-StateVar
+Version:        1.1.0.1
 Release:        0
 Summary:        State variables
 Group:          System/Libraries
@@ -62,7 +62,7 @@
 
 %install
 %ghc_lib_install
-
+sed -i 's/\r//g' LICENSE README.md
 
 %post devel
 %ghc_pkg_recache

++++++ StateVar-1.1.0.0.tar.gz -> StateVar-1.1.0.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/StateVar-1.1.0.0/CHANGELOG.md 
new/StateVar-1.1.0.1/CHANGELOG.md
--- old/StateVar-1.1.0.0/CHANGELOG.md   2015-03-09 15:44:29.000000000 +0100
+++ new/StateVar-1.1.0.1/CHANGELOG.md   2015-08-05 16:35:49.000000000 +0200
@@ -1,5 +1,23 @@
-1.1
----
-* Melded the API of `foreign-var` 0.1 with the API of `StateVar` 1.0.1.1
-* Introduced `HasUpdate`, which permits a wider array of uses of these 
combinators, including usecases that must update atomically.
-* Switched to multi-parameter typeclasses. This permits `Ptr a` to be directly 
employed as an instance of `HasGetter`, `HasUpdate`, and `HasSetter`.
+1.1.0.1
+-------
+* Documentation changes only.
+
+1.1.0.0
+-------
+* Melded the API of `foreign-var` 0.1 with the API of `StateVar` 1.0.1.1
+* Introduced `HasUpdate`, which permits a wider array of uses of these 
combinators, including usecases that must update atomically.
+* Switched to multi-parameter typeclasses. This permits `Ptr a` to be directly 
employed as an instance of `HasGetter`, `HasUpdate`, and `HasSetter`.
+
+1.0.1.1
+-------
+* Infrastructure changes only.
+
+1.0.1.0
+-------
+* Exposed `GettableStateVar`, `SettableStateVar` and `StateVar` constructors 
to make writing own instances possible.
+* Added `Functor`, `Applicative` and `Monad` instances for `GettableStateVar`.
+* Various infrastructure improvements.
+
+1.0.0.0
+-------
+* Initial release.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/StateVar-1.1.0.0/LICENSE new/StateVar-1.1.0.1/LICENSE
--- old/StateVar-1.1.0.0/LICENSE        2015-03-09 15:44:29.000000000 +0100
+++ new/StateVar-1.1.0.1/LICENSE        2015-08-05 16:35:49.000000000 +0200
@@ -1,29 +1,29 @@
-Copyright (c) 2014-2015, Edward Kmett
-Copyright (c) 2009-2014, 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.
+Copyright (c) 2014-2015, Edward Kmett
+Copyright (c) 2009-2014, 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.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/StateVar-1.1.0.0/README.md 
new/StateVar-1.1.0.1/README.md
--- old/StateVar-1.1.0.0/README.md      2015-03-09 15:44:29.000000000 +0100
+++ new/StateVar-1.1.0.1/README.md      2015-08-05 16:35:49.000000000 +0200
@@ -1 +1 @@
-[![Hackage](https://img.shields.io/hackage/v/StateVar.svg)](https://hackage.haskell.org/package/StateVar)
 [![Build 
Status](https://travis-ci.org/haskell-opengl/StateVar.png)](https://travis-ci.org/haskell-opengl/StateVar)
+[![Hackage](https://img.shields.io/hackage/v/StateVar.svg)](https://hackage.haskell.org/package/StateVar)
 [![Build 
Status](https://travis-ci.org/haskell-opengl/StateVar.png)](https://travis-ci.org/haskell-opengl/StateVar)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/StateVar-1.1.0.0/Setup.hs 
new/StateVar-1.1.0.1/Setup.hs
--- old/StateVar-1.1.0.0/Setup.hs       2015-03-09 15:44:29.000000000 +0100
+++ new/StateVar-1.1.0.1/Setup.hs       2015-08-05 16:35:49.000000000 +0200
@@ -1,2 +1,2 @@
-import Distribution.Simple
-main = defaultMain
+import Distribution.Simple
+main = defaultMain
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/StateVar-1.1.0.0/StateVar.cabal 
new/StateVar-1.1.0.1/StateVar.cabal
--- old/StateVar-1.1.0.0/StateVar.cabal 2015-03-09 15:44:29.000000000 +0100
+++ new/StateVar-1.1.0.1/StateVar.cabal 2015-08-05 16:35:49.000000000 +0200
@@ -1,46 +1,46 @@
-name: StateVar
-version: 1.1.0.0
-synopsis: State variables
-description:
-  This package contains state variables, which are references in the IO monad,
-  like IORefs or parts of the OpenGL state.
-homepage: https://github.com/haskell-opengl/StateVar
-bug-reports: https://github.com/haskell-opengl/StateVar/issues
-copyright: Copyright (C) 2014-2015 Edward A. Kmett, 2009-2014 Sven Panne
-license: BSD3
-license-file: LICENSE
-author: Sven Panne and Edward Kmett
-maintainer: Sven Panne <svenpa...@gmail.com>
-category: Data
-build-type: Simple
-cabal-version: >=1.10
-extra-source-files: README.md CHANGELOG.md
-
-library
-  exposed-modules:
-    Data.StateVar
-
-  build-depends:
-    base         >= 4   && < 5,
-    stm          >= 2.0 && < 2.5,
-    transformers >= 0.2 && < 0.5
-
-  default-language: Haskell2010
-  other-extensions:
-    CPP
-    DeriveDataTypeable
-    MultiParamTypeClasses
-    FunctionalDependencies
-    FlexibleInstances
-    TypeFamilies
-
-  hs-source-dirs: src
-  ghc-options: -Wall
-
-  if impl(ghc>=7.4)
-    -- other-extensions: DefaultSignatures
-    cpp-options: -DUSE_DEFAULT_SIGNATURES=1
-
-source-repository head
-  type: git
-  location: https://github.com/haskell-opengl/StateVar.git
+name: StateVar
+version: 1.1.0.1
+synopsis: State variables
+description:
+  This package contains state variables, which are references in the IO monad,
+  like IORefs or parts of the OpenGL state.
+homepage: https://github.com/haskell-opengl/StateVar
+bug-reports: https://github.com/haskell-opengl/StateVar/issues
+copyright: Copyright (C) 2014-2015 Edward A. Kmett, 2009-2015 Sven Panne
+license: BSD3
+license-file: LICENSE
+author: Sven Panne and Edward Kmett
+maintainer: Sven Panne <svenpa...@gmail.com>
+category: Data
+build-type: Simple
+cabal-version: >=1.10
+extra-source-files: README.md CHANGELOG.md
+
+library
+  exposed-modules:
+    Data.StateVar
+
+  build-depends:
+    base         >= 4   && < 5,
+    stm          >= 2.0 && < 2.5,
+    transformers >= 0.2 && < 0.5
+
+  default-language: Haskell2010
+  other-extensions:
+    CPP
+    DeriveDataTypeable
+    MultiParamTypeClasses
+    FunctionalDependencies
+    FlexibleInstances
+    TypeFamilies
+
+  hs-source-dirs: src
+  ghc-options: -Wall
+
+  if impl(ghc>=7.4)
+    -- other-extensions: DefaultSignatures
+    cpp-options: -DUSE_DEFAULT_SIGNATURES=1
+
+source-repository head
+  type: git
+  location: https://github.com/haskell-opengl/StateVar.git
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/StateVar-1.1.0.0/src/Data/StateVar.hs 
new/StateVar-1.1.0.1/src/Data/StateVar.hs
--- old/StateVar-1.1.0.0/src/Data/StateVar.hs   2015-03-09 15:44:29.000000000 
+0100
+++ new/StateVar-1.1.0.1/src/Data/StateVar.hs   2015-08-05 16:35:49.000000000 
+0200
@@ -1,278 +1,276 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE FunctionalDependencies #-}
-{-# LANGUAGE FlexibleInstances #-}
-#if USE_DEFAULT_SIGNATURES
-{-# LANGUAGE DefaultSignatures #-}
-#endif
-{-# LANGUAGE TypeFamilies #-}
---------------------------------------------------------------------------------
--- |
--- Module      :  Data.StateVar
--- Copyright   :  (c) Edward Kmett 2014-2015, Sven Panne 2009-2014
--- License     :  BSD3
--- 
--- Maintainer  :  Sven Panne <svenpa...@gmail.com>
--- 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 could 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
--- @
---
--- However, 'Ptr' can be used directly through the same API:
---
--- @
---   do p <- malloc :: IO (Ptr Int)
---      p $= 11
---      p $~ (+ 22)
---      x <- get p
---      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(get)
-  , GettableStateVar, makeGettableStateVar
-  -- * Writable State Variables
-  , HasSetter(($=)), ($=!)
-  , SettableStateVar(SettableStateVar), makeSettableStateVar
-  -- * Updatable State Variables
-  , HasUpdate(($~), ($~!))
-  , StateVar(StateVar), makeStateVar
-  , mapStateVar
-  ) where
-
-import Control.Concurrent.STM
-import Control.Monad.IO.Class
-import Data.IORef
-import Data.Typeable
-import Foreign.Ptr
-import Foreign.Storable
-
---------------------------------------------------------------------
--- * StateVar
---------------------------------------------------------------------
-
--- | 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.
---
--- This data type represents a piece of mutable, imperative state
--- with possible side-effects. These tend to encapsulate all sorts
--- tricky behavior in external libraries, and may well throw
--- exceptions.
---
--- Inhabitants __should__ satsify the following properties.
---
--- In the absence of concurrent mutation from other threads or a
--- thrown exception:
---
--- @
--- do x <- 'get' v; v '$=' y; v '$=' x
--- @
---
--- should restore the previous state.
---
--- Ideally, in the absence of thrown exceptions:
---
--- @
--- v '$=' a >> 'get' v
--- @
---
--- should return @a@, regardless of @a@. In practice some 'StateVar's only
--- permit a very limited range of value assignments, and do not report failure.
-data StateVar a = StateVar (IO a) (a -> IO ()) deriving Typeable
-
--- | Construct a 'StateVar' from two IO actions, one for reading and one for
---- writing.
-makeStateVar
-  :: IO a         -- ^ getter
-  -> (a -> IO ()) -- ^ setter
-  -> StateVar a
-makeStateVar = StateVar
-
--- | Change the type of a 'StateVar'
-mapStateVar :: (b -> a) -> (a -> b) -> StateVar a -> StateVar b
-mapStateVar ba ab (StateVar ga sa) = StateVar (fmap ab ga) (sa . ba)
-{-# INLINE mapStateVar #-}
-
--- | A concrete implementation of a write-only state variable, carrying an IO
--- action to write the new value.
-newtype SettableStateVar a = SettableStateVar (a -> IO ())
-  deriving Typeable
-
--- | Construct a 'SettableStateVar' from an IO action for writing.
-makeSettableStateVar
-  :: (a -> IO ()) -- ^ setter
-  -> SettableStateVar a
-makeSettableStateVar = SettableStateVar
-{-# INLINE makeSettableStateVar #-}
-
--- | A concrete implementation of a read-only state variable is simply an IO
--- action to read the value.
-type GettableStateVar = IO
-
--- | Construct a 'GettableStateVar' from an IO action.
-makeGettableStateVar
-  :: IO a -- ^ getter
-  -> GettableStateVar a
-makeGettableStateVar = id
-{-# INLINE makeGettableStateVar #-}
-
---------------------------------------------------------------------
--- * HasSetter
---------------------------------------------------------------------
-
-infixr 2 $=, $=!
-
--- | This is the class of all writable state variables.
-class HasSetter t a | t -> a where
-  -- | Write a new value into a state variable.
-  ($=) :: MonadIO m => t -> a -> m ()
-
--- | This is a variant of '$=' which is strict in the value to be set.
-($=!) :: (HasSetter t a, MonadIO m) => t -> a -> m ()
-p $=! a = (p $=) $! a
-{-# INLINE ($=!) #-}
-
-instance HasSetter (SettableStateVar a) a where
-  SettableStateVar f $= a = liftIO (f a)
-  {-# INLINE ($=) #-}
-
-instance HasSetter (StateVar a) a where
-  StateVar _ s $= a = liftIO $ s a
-  {-# INLINE ($=) #-}
-
-instance Storable a => HasSetter (Ptr a) a where
-  p $= a = liftIO $ poke p a
-  {-# INLINE ($=) #-}
-
-instance HasSetter (IORef a) a where
-  p $= a = liftIO $ writeIORef p a
-  {-# INLINE ($=) #-}
-
-instance HasSetter (TVar a) a where
-  p $= a = liftIO $ atomically $ writeTVar p a
-  {-# INLINE ($=) #-}
-
---------------------------------------------------------------------
--- * HasUpdate
---------------------------------------------------------------------
-
-infixr 2 $~, $~!
-
-class HasSetter t a => HasUpdate t a b | t -> a b where
-  -- | Transform the contents of a state variable with a given funtion.
-  ($~) :: MonadIO m => t -> (a -> b) -> m ()
-#if USE_DEFAULT_SIGNATURES
-  default ($~) :: (MonadIO m, a ~ b, HasGetter t a, HasSetter t a) => t -> (a 
-> b) -> m ()
-  ($~) = defaultUpdate
-#endif
-  -- | This is a variant of '$~' which is strict in the transformed value.
-  ($~!) :: MonadIO m => t -> (a -> b) -> m ()
-#if USE_DEFAULT_SIGNATURES
-  default ($~!) :: (MonadIO m, a ~ b, HasGetter t a, HasSetter t a) => t -> (a 
-> b) -> m ()
-  ($~!) = defaultUpdateStrict
-#endif
-
-defaultUpdate :: (MonadIO m, a ~ b, HasGetter t a, HasSetter t a) => t -> (a 
-> b) -> m ()
-defaultUpdate r f = liftIO $ do
-  a <- get r
-  r $= f a
-
-defaultUpdateStrict :: (MonadIO m, a ~ b, HasGetter t a, HasSetter t a) => t 
-> (a -> b) -> m ()
-defaultUpdateStrict r f = liftIO $ do
-  a <- get r
-  r $=! f a
-
-instance HasUpdate (StateVar a) a a where
-  ($~) = defaultUpdate
-  ($~!) = defaultUpdateStrict
-
-instance Storable a => HasUpdate (Ptr a) a a where
-  ($~) = defaultUpdate
-  ($~!) = defaultUpdateStrict
-
-instance HasUpdate (IORef a) a a where
-  r $~ f  = liftIO $ atomicModifyIORef r $ \a -> (f a,())
-#if __GLASGOW_HASKELL__ >= 706
-  r $~! f = liftIO $ atomicModifyIORef' r $ \a -> (f a,())
-#else
-  r $~! f = liftIO $ do
-    s <- atomicModifyIORef r $ \a -> let s = f a in (s, s)
-    s `seq` return ()
-#endif
-
-instance HasUpdate (TVar a) a a where
-  r $~ f = liftIO $ atomically $ do
-    a <- readTVar r
-    writeTVar r (f a)
-  r $~! f = liftIO $ atomically $ do
-    a <- readTVar r
-    writeTVar r $! f a
-
---------------------------------------------------------------------
--- * HasGetter
---------------------------------------------------------------------
-
-class HasGetter t a | t -> a where
-  get :: MonadIO m => t -> m a
-
-instance HasGetter (StateVar a) a where
-  get (StateVar g _) = liftIO g
-  {-# INLINE get #-}
-
-instance HasGetter (TVar a) a where
-  get = liftIO . atomically . readTVar
-  {-# INLINE get #-}
-
-instance HasGetter (IO a) a where
-  get = liftIO
-  {-# INLINE get #-}
-
-instance HasGetter (STM a) a where
-  get = liftIO . atomically
-  {-# INLINE get #-}
-
-instance Storable a => HasGetter (Ptr a) a where
-  get = liftIO . peek
-  {-# INLINE get #-}
-
-instance HasGetter (IORef a) a where
-  get = liftIO . readIORef
-  {-# INLINE get #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE FlexibleInstances #-}
+#if USE_DEFAULT_SIGNATURES
+{-# LANGUAGE DefaultSignatures #-}
+#endif
+{-# LANGUAGE TypeFamilies #-}
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Data.StateVar
+-- Copyright   :  (c) Edward Kmett 2014-2015, Sven Panne 2009-2014
+-- License     :  BSD3
+-- 
+-- Maintainer  :  Sven Panne <svenpa...@gmail.com>
+-- 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 could 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
+-- @
+--
+-- However, 'Ptr' can be used directly through the same API:
+--
+-- @
+--   do p <- malloc :: IO (Ptr Int)
+--      p $= 11
+--      p $~ (+ 22)
+--      x <- get p
+--      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(get)
+  , GettableStateVar, makeGettableStateVar
+  -- * Writable State Variables
+  , HasSetter(($=)), ($=!)
+  , SettableStateVar(SettableStateVar), makeSettableStateVar
+  -- * Updatable State Variables
+  , HasUpdate(($~), ($~!))
+  , StateVar(StateVar), makeStateVar
+  , mapStateVar
+  ) where
+
+import Control.Concurrent.STM
+import Control.Monad.IO.Class
+import Data.IORef
+import Data.Typeable
+import Foreign.Ptr
+import Foreign.Storable
+
+--------------------------------------------------------------------
+-- * StateVar
+--------------------------------------------------------------------
+
+-- | 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. This data type represents a piece of mutable, imperative state
+-- with possible side-effects. These tend to encapsulate all sorts tricky
+-- behavior in external libraries, and may well throw exceptions. Inhabitants
+-- __should__ satsify the following properties:
+--
+-- * In the absence of concurrent mutation from other threads or a thrown
+-- exception:
+--
+-- @
+-- do x <- 'get' v; v '$=' y; v '$=' x
+-- @
+--
+-- should restore the previous state.
+--
+-- * Ideally, in the absence of thrown exceptions:
+--
+-- @
+-- v '$=' a >> 'get' v
+-- @
+--
+-- should return @a@, regardless of @a@. In practice some 'StateVar's only
+-- permit a very limited range of value assignments, and do not report failure.
+data StateVar a = StateVar (IO a) (a -> IO ()) deriving Typeable
+
+-- | Construct a 'StateVar' from two IO actions, one for reading and one for
+--- writing.
+makeStateVar
+  :: IO a         -- ^ getter
+  -> (a -> IO ()) -- ^ setter
+  -> StateVar a
+makeStateVar = StateVar
+
+-- | Change the type of a 'StateVar'
+mapStateVar :: (b -> a) -> (a -> b) -> StateVar a -> StateVar b
+mapStateVar ba ab (StateVar ga sa) = StateVar (fmap ab ga) (sa . ba)
+{-# INLINE mapStateVar #-}
+
+-- | A concrete implementation of a write-only state variable, carrying an IO
+-- action to write the new value.
+newtype SettableStateVar a = SettableStateVar (a -> IO ())
+  deriving Typeable
+
+-- | Construct a 'SettableStateVar' from an IO action for writing.
+makeSettableStateVar
+  :: (a -> IO ()) -- ^ setter
+  -> SettableStateVar a
+makeSettableStateVar = SettableStateVar
+{-# INLINE makeSettableStateVar #-}
+
+-- | A concrete implementation of a read-only state variable is simply an IO
+-- action to read the value.
+type GettableStateVar = IO
+
+-- | Construct a 'GettableStateVar' from an IO action.
+makeGettableStateVar
+  :: IO a -- ^ getter
+  -> GettableStateVar a
+makeGettableStateVar = id
+{-# INLINE makeGettableStateVar #-}
+
+--------------------------------------------------------------------
+-- * HasSetter
+--------------------------------------------------------------------
+
+infixr 2 $=, $=!
+
+-- | This is the class of all writable state variables.
+class HasSetter t a | t -> a where
+  -- | Write a new value into a state variable.
+  ($=) :: MonadIO m => t -> a -> m ()
+
+-- | This is a variant of '$=' which is strict in the value to be set.
+($=!) :: (HasSetter t a, MonadIO m) => t -> a -> m ()
+p $=! a = (p $=) $! a
+{-# INLINE ($=!) #-}
+
+instance HasSetter (SettableStateVar a) a where
+  SettableStateVar f $= a = liftIO (f a)
+  {-# INLINE ($=) #-}
+
+instance HasSetter (StateVar a) a where
+  StateVar _ s $= a = liftIO $ s a
+  {-# INLINE ($=) #-}
+
+instance Storable a => HasSetter (Ptr a) a where
+  p $= a = liftIO $ poke p a
+  {-# INLINE ($=) #-}
+
+instance HasSetter (IORef a) a where
+  p $= a = liftIO $ writeIORef p a
+  {-# INLINE ($=) #-}
+
+instance HasSetter (TVar a) a where
+  p $= a = liftIO $ atomically $ writeTVar p a
+  {-# INLINE ($=) #-}
+
+--------------------------------------------------------------------
+-- * HasUpdate
+--------------------------------------------------------------------
+
+infixr 2 $~, $~!
+
+-- | This is the class of all updatable state variables.
+class HasSetter t a => HasUpdate t a b | t -> a b where
+  -- | Transform the contents of a state variable with a given funtion.
+  ($~) :: MonadIO m => t -> (a -> b) -> m ()
+#if USE_DEFAULT_SIGNATURES
+  default ($~) :: (MonadIO m, a ~ b, HasGetter t a, HasSetter t a) => t -> (a 
-> b) -> m ()
+  ($~) = defaultUpdate
+#endif
+  -- | This is a variant of '$~' which is strict in the transformed value.
+  ($~!) :: MonadIO m => t -> (a -> b) -> m ()
+#if USE_DEFAULT_SIGNATURES
+  default ($~!) :: (MonadIO m, a ~ b, HasGetter t a, HasSetter t a) => t -> (a 
-> b) -> m ()
+  ($~!) = defaultUpdateStrict
+#endif
+
+defaultUpdate :: (MonadIO m, a ~ b, HasGetter t a, HasSetter t a) => t -> (a 
-> b) -> m ()
+defaultUpdate r f = liftIO $ do
+  a <- get r
+  r $= f a
+
+defaultUpdateStrict :: (MonadIO m, a ~ b, HasGetter t a, HasSetter t a) => t 
-> (a -> b) -> m ()
+defaultUpdateStrict r f = liftIO $ do
+  a <- get r
+  r $=! f a
+
+instance HasUpdate (StateVar a) a a where
+  ($~) = defaultUpdate
+  ($~!) = defaultUpdateStrict
+
+instance Storable a => HasUpdate (Ptr a) a a where
+  ($~) = defaultUpdate
+  ($~!) = defaultUpdateStrict
+
+instance HasUpdate (IORef a) a a where
+  r $~ f  = liftIO $ atomicModifyIORef r $ \a -> (f a,())
+#if __GLASGOW_HASKELL__ >= 706
+  r $~! f = liftIO $ atomicModifyIORef' r $ \a -> (f a,())
+#else
+  r $~! f = liftIO $ do
+    s <- atomicModifyIORef r $ \a -> let s = f a in (s, s)
+    s `seq` return ()
+#endif
+
+instance HasUpdate (TVar a) a a where
+  r $~ f = liftIO $ atomically $ do
+    a <- readTVar r
+    writeTVar r (f a)
+  r $~! f = liftIO $ atomically $ do
+    a <- readTVar r
+    writeTVar r $! f a
+
+--------------------------------------------------------------------
+-- * HasGetter
+--------------------------------------------------------------------
+
+-- | This is the class of all readable state variables.
+class HasGetter t a | t -> a where
+  get :: MonadIO m => t -> m a
+
+instance HasGetter (StateVar a) a where
+  get (StateVar g _) = liftIO g
+  {-# INLINE get #-}
+
+instance HasGetter (TVar a) a where
+  get = liftIO . atomically . readTVar
+  {-# INLINE get #-}
+
+instance HasGetter (IO a) a where
+  get = liftIO
+  {-# INLINE get #-}
+
+instance HasGetter (STM a) a where
+  get = liftIO . atomically
+  {-# INLINE get #-}
+
+instance Storable a => HasGetter (Ptr a) a where
+  get = liftIO . peek
+  {-# INLINE get #-}
+
+instance HasGetter (IORef a) a where
+  get = liftIO . readIORef
+  {-# INLINE get #-}


Reply via email to