diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+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`.
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,5 @@
-Copyright (c) 2009, Sven Panne
+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
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +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)
diff --git a/StateVar.cabal b/StateVar.cabal
--- a/StateVar.cabal
+++ b/StateVar.cabal
@@ -1,25 +1,45 @@
 name: StateVar
-version: 1.0.1.1
+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
+author: Sven Panne and Edward Kmett
 maintainer: Sven Panne <svenpanne@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 >= 3 && < 5
+  exposed-modules:
+    Data.StateVar
+
+  build-depends:
+    base         >= 4   && < 5,
+    stm          >= 2.0 && < 2.5,
+    transformers >= 0.2 && < 0.5
+
   default-language: Haskell2010
-  hs-Source-Dirs: src
+  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
diff --git a/src/Data/StateVar.hs b/src/Data/StateVar.hs
--- a/src/Data/StateVar.hs
+++ b/src/Data/StateVar.hs
@@ -1,7 +1,16 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE FlexibleInstances #-}
+#if USE_DEFAULT_SIGNATURES
+{-# LANGUAGE DefaultSignatures #-}
+#endif
+{-# LANGUAGE TypeFamilies #-}
 --------------------------------------------------------------------------------
 -- |
 -- Module      :  Data.StateVar
--- Copyright   :  (c) Sven Panne 2014
+-- Copyright   :  (c) Edward Kmett 2014-2015, Sven Panne 2009-2014
 -- License     :  BSD3
 -- 
 -- Maintainer  :  Sven Panne <svenpanne@gmail.com>
@@ -12,7 +21,7 @@
 -- 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':
+-- buffer. This buffer could easily be converted into a 'StateVar':
 --
 -- @
 -- makeStateVarFromPtr :: Storable a => Ptr a -> StateVar a
@@ -32,6 +41,16 @@
 --      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:
 --
@@ -44,117 +63,216 @@
 -- @
 --------------------------------------------------------------------------------
 
-module Data.StateVar (
-   -- * Readable State Variables
-   HasGetter(..),
-   GettableStateVar(..), makeGettableStateVar,
-   -- * Writable State Variables
-   HasSetter(..),
-   SettableStateVar(..), makeSettableStateVar,
-   -- * General State Variables
-   StateVar(..), makeStateVar,
-   -- * Utility Functions
-   ($~), ($=!), ($~!)
-) where
+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.Applicative ( Applicative(..) )
-import Data.IORef ( IORef, readIORef, writeIORef )
+import Control.Concurrent.STM
+import Control.Monad.IO.Class
+import Data.IORef
+import Data.Typeable
+import Foreign.Ptr
+import Foreign.Storable
 
---------------------------------------------------------------------------------
+--------------------------------------------------------------------
+-- * StateVar
+--------------------------------------------------------------------
 
-infixr 2 $=
+-- | 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
 
--- | The class of all readable state variables.
-class HasGetter g where
-   -- | Read the value of a state variable.
-   get :: g a -> IO a
+-- | 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 #-}
 
-instance HasGetter IORef where
-   get = readIORef
+-- | 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
 
--- | A concrete implementation of a read-only state variable, carrying an IO
+-- | 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.
-newtype GettableStateVar a = GettableStateVar (IO a)
+type GettableStateVar = IO
 
-instance HasGetter GettableStateVar where
-   get (GettableStateVar g) = g
+-- | Construct a 'GettableStateVar' from an IO action.
+makeGettableStateVar
+  :: IO a -- ^ getter
+  -> GettableStateVar a
+makeGettableStateVar = id
+{-# INLINE makeGettableStateVar #-}
 
-instance Functor GettableStateVar where
-  fmap f (GettableStateVar g) = GettableStateVar (fmap f g)
+--------------------------------------------------------------------
+-- * HasSetter
+--------------------------------------------------------------------
 
-instance Applicative GettableStateVar where
-  pure = GettableStateVar . pure
-  GettableStateVar g <*> GettableStateVar h = GettableStateVar (g <*> h)
+infixr 2 $=, $=!
 
-instance Monad GettableStateVar where
-  return = pure
-  GettableStateVar g >>= h = GettableStateVar (g >>= get . h)
+-- | 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 ()
 
--- | Construct a 'GettableStateVar' from an IO action.
-makeGettableStateVar :: IO a -> GettableStateVar a
-makeGettableStateVar = GettableStateVar
+-- | 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 ($=) #-}
 
--- | 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 (StateVar a) a where
+  StateVar _ s $= a = liftIO $ s a
+  {-# INLINE ($=) #-}
 
-instance HasSetter IORef where
-   ($=) = writeIORef
+instance Storable a => HasSetter (Ptr a) a where
+  p $= a = liftIO $ poke p a
+  {-# INLINE ($=) #-}
 
--- | 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 (IORef a) a where
+  p $= a = liftIO $ writeIORef p a
+  {-# INLINE ($=) #-}
 
-instance HasSetter SettableStateVar where
-   ($=) (SettableStateVar s) a = s a
+instance HasSetter (TVar a) a where
+  p $= a = liftIO $ atomically $ writeTVar p a
+  {-# INLINE ($=) #-}
 
--- instance Contravariant SettableStateVar where
---    contramap f (SettableStateVar s) = SettableStateVar (s . f)
+--------------------------------------------------------------------
+-- * HasUpdate
+--------------------------------------------------------------------
 
--- | Construct a 'SettableStateVar' from an IO action.
-makeSettableStateVar :: (a -> IO ()) -> SettableStateVar a
-makeSettableStateVar = SettableStateVar
+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
 
--- | 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)
+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
 
-instance HasGetter StateVar where
-   get (StateVar g _) = get g
+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 HasSetter StateVar where
-   ($=) (StateVar _ s) a = s $= a
+instance HasUpdate (StateVar a) a a where
+  ($~) = defaultUpdate
+  ($~!) = defaultUpdateStrict
 
--- | 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)
+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
 
--- | A modificator convenience function, transforming the contents of a state
--- variable with a given funtion.
+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 v, HasSetter v) => v a -> (a -> a) -> IO ()
-v $~ f = do
-   x <- get v
-   v $= f x
+--------------------------------------------------------------------
+-- * HasGetter
+--------------------------------------------------------------------
 
--- | A variant of '$=' which is strict in the value to be set.
-($=!) :: HasSetter s => s a -> a -> IO ()
-v $=! x = x `seq` v $= x
+class HasGetter t a | t -> a where
+  get :: MonadIO m => t -> m a
 
--- | 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
+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 #-}
