diff --git a/src/Quasar/Awaitable.hs b/src/Quasar/Awaitable.hs
index 6933fb87df6cfe58197abaf3e3ece942bcbca5d7..0f8d3115cb9d9226054c6e7a9e3b358d0c96c424 100644
--- a/src/Quasar/Awaitable.hs
+++ b/src/Quasar/Awaitable.hs
@@ -1,4 +1,5 @@
 module Quasar.Awaitable (
+  -- * Awaitable
   IsAwaitable(..),
   awaitSTM,
   Awaitable,
@@ -7,8 +8,20 @@ module Quasar.Awaitable (
   completedAwaitable,
   awaitableFromSTM,
   peekAwaitable,
-) where
 
+  -- * AsyncVar
+  AsyncVar,
+  newAsyncVar,
+  newAsyncVarSTM,
+  putAsyncVarEither,
+  putAsyncVarEitherSTM,
+  putAsyncVar,
+  putAsyncVar_,
+  failAsyncVar,
+  failAsyncVar_,
+  putAsyncVarEither_,
+  putAsyncVarEitherSTM_,
+) where
 
 import Control.Concurrent.STM
 import Control.Monad.Catch
@@ -65,3 +78,45 @@ awaitableFromSTM fn = do
         pure value
       Right value -> pure value
 
+
+
+-- ** AsyncVar
+
+-- | The default implementation for an `Awaitable` that can be fulfilled later.
+newtype AsyncVar r = AsyncVar (TMVar (Either SomeException r))
+
+instance IsAwaitable r (AsyncVar r) where
+  peekSTM (AsyncVar var) = tryReadTMVar var
+
+
+newAsyncVarSTM :: STM (AsyncVar r)
+newAsyncVarSTM = AsyncVar <$> newEmptyTMVar
+
+newAsyncVar :: MonadIO m => m (AsyncVar r)
+newAsyncVar = liftIO $ AsyncVar <$> newEmptyTMVarIO
+
+
+putAsyncVarEither :: forall a m. MonadIO m => AsyncVar a -> Either SomeException a -> m Bool
+putAsyncVarEither var = liftIO . atomically . putAsyncVarEitherSTM var
+
+putAsyncVarEitherSTM :: AsyncVar a -> Either SomeException a -> STM Bool
+putAsyncVarEitherSTM (AsyncVar var) = tryPutTMVar var
+
+
+putAsyncVar :: MonadIO m => AsyncVar a -> a -> m Bool
+putAsyncVar var = putAsyncVarEither var . Right
+
+putAsyncVar_ :: MonadIO m => AsyncVar a -> a -> m ()
+putAsyncVar_ var = void . putAsyncVar var
+
+failAsyncVar :: MonadIO m => AsyncVar a -> SomeException -> m Bool
+failAsyncVar var = putAsyncVarEither var . Left
+
+failAsyncVar_ :: MonadIO m => AsyncVar a -> SomeException -> m ()
+failAsyncVar_ var = void . failAsyncVar var
+
+putAsyncVarEither_ :: MonadIO m => AsyncVar a -> Either SomeException a -> m ()
+putAsyncVarEither_ var = void . putAsyncVarEither var
+
+putAsyncVarEitherSTM_ :: AsyncVar a -> Either SomeException a -> STM ()
+putAsyncVarEitherSTM_ var = void . putAsyncVarEitherSTM var
diff --git a/src/Quasar/Core.hs b/src/Quasar/Core.hs
index 863b7e8b98ed666dcfb89965f6921705bb2c74d6..b5e56e4dd8a60d1cbaedbaf1f4e4e2c25faa5775 100644
--- a/src/Quasar/Core.hs
+++ b/src/Quasar/Core.hs
@@ -6,11 +6,6 @@ module Quasar.Core (
   runAsyncIO,
   awaitResult,
 
-  -- * AsyncVar
-  AsyncVar,
-  newAsyncVar,
-  putAsyncVar,
-
   -- * Cancellation
   withCancellationToken,
 ) where
@@ -136,52 +131,6 @@ awaitResult = (await =<<)
 --  asyncThread :: m r -> AsyncIO r
 
 
--- * Async helpers
-
--- ** AsyncVar
-
--- | The default implementation for an `Awaitable` that can be fulfilled later.
-newtype AsyncVar r = AsyncVar (TMVar (Either SomeException r))
-
-instance IsAwaitable r (AsyncVar r) where
-  peekSTM (AsyncVar var) = tryReadTMVar var
-
-tryPutAsyncVarEitherSTM :: AsyncVar a -> Either SomeException a -> STM Bool
-tryPutAsyncVarEitherSTM (AsyncVar var) = tryPutTMVar var
-
-tryPutAsyncVarEither :: forall a m. MonadIO m => AsyncVar a -> Either SomeException a -> m Bool
-tryPutAsyncVarEither var = liftIO . atomically . tryPutAsyncVarEitherSTM var
-
-
-newAsyncVarSTM :: STM (AsyncVar r)
-newAsyncVarSTM = AsyncVar <$> newEmptyTMVar
-
-newAsyncVar :: MonadIO m => m (AsyncVar r)
-newAsyncVar = liftIO $ AsyncVar <$> newEmptyTMVarIO
-
-
-putAsyncVar :: MonadIO m => AsyncVar a -> a -> m ()
-putAsyncVar var = putAsyncVarEither var . Right
-
-tryPutAsyncVar :: MonadIO m => AsyncVar a -> a -> m Bool
-tryPutAsyncVar var = tryPutAsyncVarEither var . Right
-
-tryPutAsyncVar_ :: MonadIO m => AsyncVar a -> a -> m ()
-tryPutAsyncVar_ var = void . tryPutAsyncVar var
-
-failAsyncVar :: MonadIO m => AsyncVar a -> SomeException -> m Bool
-failAsyncVar var = tryPutAsyncVarEither var . Left
-
-failAsyncVar_ :: MonadIO m => AsyncVar a -> SomeException -> m ()
-failAsyncVar_ var = void . failAsyncVar var
-
-putAsyncVarEither :: MonadIO m => AsyncVar a -> Either SomeException a -> m ()
-putAsyncVarEither avar value = liftIO $ do
-  success <- tryPutAsyncVarEither avar value
-  unless success $ fail "An AsyncVar can only be fulfilled once"
-
-tryPutAsyncVarEither_ :: MonadIO m => AsyncVar a -> Either SomeException a -> m ()
-tryPutAsyncVarEither_ var = void . tryPutAsyncVarEither var
 
 
 -- * Awaiting multiple asyncs
diff --git a/test/Quasar/AsyncSpec.hs b/test/Quasar/AsyncSpec.hs
index 868a9fa4fc8b8c6cc37d0be4d8f58dff9b6ec03f..c1a00ccb07f32504ec0cfe4c11ac9b3eb83d62b7 100644
--- a/test/Quasar/AsyncSpec.hs
+++ b/test/Quasar/AsyncSpec.hs
@@ -2,7 +2,7 @@ module Quasar.AsyncSpec (spec) where
 
 import Control.Concurrent
 import Control.Concurrent.STM
-import Control.Monad (void, (<=<))
+import Control.Monad (void)
 import Control.Monad.IO.Class
 import Prelude
 import Test.Hspec
@@ -22,7 +22,7 @@ spec = parallel $ do
 
     it "accepts a value" $ do
       avar <- newAsyncVar :: IO (AsyncVar ())
-      putAsyncVar avar ()
+      putAsyncVar_ avar ()
 
   describe "AsyncIO" $ do
     it "binds pure operations" $ do
@@ -40,26 +40,26 @@ spec = parallel $ do
 
     it "can fmap the result of an already finished async" $ do
       avar <- newAsyncVar :: IO (AsyncVar ())
-      putAsyncVar avar ()
+      putAsyncVar_ avar ()
       runAsyncIO (id <$> await avar)
 
     it "can fmap the result of an async that is completed later" $ do
       avar <- newAsyncVar :: IO (AsyncVar ())
       void $ forkIO $ do
         threadDelay 100000
-        putAsyncVar avar ()
+        putAsyncVar_ avar ()
       runAsyncIO (id <$> await avar)
 
     it "can bind the result of an already finished async" $ do
       avar <- newAsyncVar :: IO (AsyncVar ())
-      putAsyncVar avar ()
+      putAsyncVar_ avar ()
       runAsyncIO (await avar >>= pure)
 
     it "can bind the result of an async that is completed later" $ do
       avar <- newAsyncVar :: IO (AsyncVar ())
       void $ forkIO $ do
         threadDelay 100000
-        putAsyncVar avar ()
+        putAsyncVar_ avar ()
       runAsyncIO (await avar >>= pure)
 
     it "can terminate when encountering an asynchronous exception" $ do