diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,7 +1,17 @@
-## 0
+## 0.3
 
-* Repository initialized
+* Support `base` 4.6
 
+## 0.2
+
+* Switched from `monad-st` to `primitive`
+
 ## 0.1
 
 * Added `runLazyIO` and `runLazyIO_`.
+
+
+## 0
+
+* Repository initialized
+
diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -1,7 +1,7 @@
 promises
 ========
 
-[![Build Status](https://secure.travis-ci.org/ekmett/promises.png?branch=master)](http://travis-ci.org/ekmett/promises)
+[![Hackage](https://img.shields.io/hackage/v/promises.svg)](https://hackage.haskell.org/package/promises) [![Build Status](https://secure.travis-ci.org/ekmett/promises.png?branch=master)](http://travis-ci.org/ekmett/promises)
 
 Lazy demand-driven promises
 
diff --git a/promises.cabal b/promises.cabal
--- a/promises.cabal
+++ b/promises.cabal
@@ -1,6 +1,6 @@
 name:          promises
 category:      Lazy, Concurrent
-version:       0.2
+version:       0.3
 license:       BSD3
 cabal-version: >= 1.10
 license-file:  LICENSE
@@ -11,7 +11,7 @@
 bug-reports:   http://github.com/ekmett/promises/issues
 copyright:     Copyright (C) 2015 Edward A. Kmett
 build-type:    Simple
-tested-with:   GHC == 7.8.4, GHC == 7.10.1, GHC == 7.11.20150615
+tested-with:   GHC == 7.8.4, GHC == 7.10.1, GHC == 7.11.20150615, GHC == 8.0.1
 synopsis:      Lazy demand-driven promises
 description:   Lazy demand-driven promises
 
@@ -34,5 +34,5 @@
     Data.Promise
 
   build-depends:
-    base      >= 4.7 && < 5,
+    base      >= 4.6 && < 5,
     primitive >= 0.6 && < 1
diff --git a/src/Data/Promise.hs b/src/Data/Promise.hs
--- a/src/Data/Promise.hs
+++ b/src/Data/Promise.hs
@@ -3,7 +3,9 @@
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE RankNTypes #-}
+#if MIN_VERSION_base(4,7,0)
 {-# LANGUAGE RoleAnnotations #-}
+#endif
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE Trustworthy #-}
 {-# OPTIONS_GHC -fno-cse -fno-full-laziness #-}
@@ -51,47 +53,6 @@
 instance Exception BrokenPromise
 
 --------------------------------------------------------------------------------
--- * Internals
---------------------------------------------------------------------------------
-
-meq :: MVar a -> MVar b -> Bool
-meq a b = a == unsafeCoerce b
-
-data K s a where
-  Pure      :: a -> K s a
-  Fulfilled :: MVar x -> IO (K s a) -> K s a
-
-instance Functor (K s) where
-  fmap f (Pure a) = Pure (f a)
-  fmap f (Fulfilled m k) = Fulfilled m (fmap (fmap f) k)
-
-pump :: a -> IO (K s x) -> MVar a -> IO (Maybe (IO (K s x)))
-pump d m v = m >>= \case
-  Pure _ -> return Nothing
-  Fulfilled u n
-    | meq u v   -> return (Just n)
-    | otherwise -> pump d n v
-
-drive :: a -> MVar (Maybe (IO (K s x))) -> MVar a -> a
-drive d mv v = unsafePerformIO $ tryTakeMVar v >>= \case
-  Just a -> return a -- if we're satisfied give the answer
-  Nothing -> takeMVar mv >>= \case -- grab the lock on this computation
-    Nothing -> do -- it has nothing left to do, so we fail to the default answer
-      putMVar mv Nothing
-      return d
-    Just k -> tryTakeMVar v >>= \case -- ok, check to make sure we haven't been satisfied in the meantime
-      Just a -> do
-        putMVar mv (Just k) -- if so, restore the continuation, and return the answer
-        return a
-      Nothing -> do
-        mk <- pump d k v
-        putMVar mv mk
-        case mk of
-          Nothing -> return d
-          Just _  -> takeMVar v
-{-# NOINLINE drive #-}
-
---------------------------------------------------------------------------------
 -- * Demand driven computations
 --------------------------------------------------------------------------------
 
@@ -99,7 +60,9 @@
 newtype Lazy s a = Lazy { getLazy :: forall x. MVar (Maybe (IO (K s x))) -> IO (K s a) }
   deriving Typeable
 
+#if MIN_VERSION_base(4,7,0)
 type role Lazy nominal representational
+#endif
 
 instance Functor (Lazy s) where
   fmap f (Lazy m) = Lazy $ \mv -> fmap go (m mv) where
@@ -206,3 +169,44 @@
 -- @
 runLazy_ :: (forall s. Promise s a -> Lazy s b) -> a
 runLazy_ k = runLazy k $ throw BrokenPromise
+
+--------------------------------------------------------------------------------
+-- * Internals
+--------------------------------------------------------------------------------
+
+meq :: MVar a -> MVar b -> Bool
+meq a b = a == unsafeCoerce b
+
+data K s a where
+  Pure      :: a -> K s a
+  Fulfilled :: MVar x -> IO (K s a) -> K s a
+
+instance Functor (K s) where
+  fmap f (Pure a) = Pure (f a)
+  fmap f (Fulfilled m k) = Fulfilled m (fmap (fmap f) k)
+
+pump :: a -> IO (K s x) -> MVar a -> IO (Maybe (IO (K s x)))
+pump d m v = m >>= \case
+  Pure _ -> return Nothing
+  Fulfilled u n
+    | meq u v   -> return (Just n)
+    | otherwise -> pump d n v
+
+drive :: a -> MVar (Maybe (IO (K s x))) -> MVar a -> a
+drive d mv v = unsafePerformIO $ tryTakeMVar v >>= \case
+  Just a -> return a -- if we're satisfied give the answer
+  Nothing -> takeMVar mv >>= \case -- grab the lock on this computation
+    Nothing -> do -- it has nothing left to do, so we fail to the default answer
+      putMVar mv Nothing
+      return d
+    Just k -> tryTakeMVar v >>= \case -- ok, check to make sure we haven't been satisfied in the meantime
+      Just a -> do
+        putMVar mv (Just k) -- if so, restore the continuation, and return the answer
+        return a
+      Nothing -> do
+        mk <- pump d k v
+        putMVar mv mk
+        case mk of
+          Nothing -> return d
+          Just _  -> takeMVar v
+{-# NOINLINE drive #-}
