diff --git a/Control/Concurrent/Actor.hs b/Control/Concurrent/Actor.hs
--- a/Control/Concurrent/Actor.hs
+++ b/Control/Concurrent/Actor.hs
@@ -20,6 +20,7 @@
     -- * Receiving Messages
     , receive
     , receiveMaybe
+    , receiveSTM
     -- * Spawning Actors
     , spawnActor
     , runActor
@@ -28,156 +29,5 @@
     , actorThread
     ) where
 
-import Control.Concurrent
-import Control.Concurrent.STM
-import Control.Monad.Reader
-
-
--- {{{ Types
-
--- {{{ Message
-
--- | The `ActorMessage` class must be implemented by any type that will be sent
--- as a message to actors.
--- Any given type of actor will have one `ActorMessage` type that is sent to
--- that actor. This ensures type safety.
--- Currently this is simply a dummy class with nothing in it, but things may be
--- added in the future.
-class ActorMessage msg
-
--- Allow actors that don't take messages.
-instance ActorMessage ()
-
--- }}}
-
--- {{{ Handle and context
-
--- | An `ActorHandle` acts as a reference to a specific actor.
-data ActorMessage msg => ActorHandle msg = ActorHandle
-    { ahContext     :: ActorContext msg     -- Context for this handle's actor.
-    , ahThread      :: ThreadId             -- The actor's thread ID.
-    }
-
--- | The `ActorContext` holds shared information about a given actor.
--- This is information such as the actor's mail box, the list of actors it's
--- linked to, etc.
-data ActorMessage msg => ActorContext msg = ActorContext
-    { acMailBox :: MailBox msg  -- Channel for the actor's messages.
-    }
-
--- | The type for the actor's mail box.
-type MailBox msg = TChan msg
-
--- }}}
-
--- }}}
-
--- | The base actor monad.
-type ActorM msg = ReaderT (ActorContext msg) IO
-
--- {{{ Get info
-
--- | Gets a handle to the current actor.
-self :: ActorMessage msg => ActorM msg (ActorHandle msg)
-self = do
-    context <- ask
-    thread <- liftIO $ myThreadId
-    return $ ActorHandle context thread
-
--- | Retrieves the mail box for the current actor.
-myMailBox :: ActorMessage msg => ActorM msg (MailBox msg)
-myMailBox = asks acMailBox
-
--- }}}
-
--- {{{ Receiving
-
--- | Reads a message from the actor's mail box.
--- If there are no messages, blocks until one is received. If you don't want
--- this, use `receiveMaybe` instead.
-receive :: ActorMessage msg => ActorM msg (msg)
-receive = do
-    chan <- myMailBox
-    -- Read from the channel, retrying if there is nothing to read.
-    liftIO $ atomically $ readTChan chan
-
--- | Reads a message from the actor's mail box.
--- If there are no messages, returns `Nothing`.
-receiveMaybe :: ActorMessage msg => ActorM msg (Maybe msg)
-receiveMaybe = do
-    chan <- myMailBox
-    liftIO $ atomically $ tryReadTChan chan
-
--- }}}
-
--- {{{ Sending
-
--- | Sends a message to the given actor handle.
--- This is secretly just `sendIO` lifted into an actor monad.
-send :: (ActorMessage msg, ActorMessage msg') =>
-        ActorHandle msg -> msg -> ActorM msg' ()
-send hand msg = liftIO $ sendIO hand msg
-
--- | Sends a message to the given actor handle from within the IO monad.
-sendIO :: ActorMessage msg => ActorHandle msg -> msg -> IO ()
-sendIO hand msg =
-    atomically $ writeTChan mailBox $ msg
-  where
-    mailBox = handleMailBox hand
-
--- }}}
-
--- {{{ Spawning
-
--- | Internal function for starting actors.
--- This takes an `ActorM` action, makes a channel for it, wraps it in exception
--- handling stuff, and turns it into an IO monad. The function returns a tuple
--- containing the actor's context and the IO action to execute the actor.
-wrapActor :: ActorMessage msg => ActorM msg () -> IO (IO (), ActorContext msg)
-wrapActor actorAction = do
-    -- TODO: Exception handling.
-    -- First, create a channel for the actor.
-    chan <- atomically newTChan
-    -- Next, create the context and run the ReaderT action.
-    let context = ActorContext chan
-        ioAction = runReaderT actorAction context
-    -- Return the information.
-    return (ioAction, context)
-
-
--- | Spawns the given actor on another thread and returns a handle to it.
-spawnActor :: ActorMessage msg => ActorM msg () -> IO (ActorHandle msg)
-spawnActor actorAction = do
-    -- Wrap the actor action.
-    (ioAction, context) <- wrapActor actorAction
-    -- Fork the actor's IO action to another thread.
-    thread <- forkIO ioAction
-    -- Return the handle.
-    return $ ActorHandle context thread
-
--- | Runs the given actor on the current thread.
--- This function effectively turns the current thread into the actor's thread.
--- Obviously, this means that this function will block until the actor exits.
--- You probably want to use this for your "main" actor.
-runActor :: ActorMessage msg => ActorM msg () -> IO ()
-runActor actorAction = do
-    -- Wrap the actor action. We discard the context, because we won't be
-    -- returning a handle to this actor.
-    (ioAction, _) <- wrapActor actorAction
-    -- Execute the IO action on the current thread.
-    ioAction
-
--- }}}
-
--- {{{ Utility functions
-
--- | Gets the mail box for the given handle.
-handleMailBox :: ActorMessage msg => ActorHandle msg -> MailBox msg
-handleMailBox = acMailBox . ahContext
-
--- | Gets the thread ID for the given actor handle.
-actorThread :: ActorMessage msg => ActorHandle msg -> ThreadId
-actorThread = ahThread
-
--- }}}
+import Control.Concurrent.Actor.Internal
 
diff --git a/Control/Concurrent/Actor/Internal.hs b/Control/Concurrent/Actor/Internal.hs
new file mode 100644
--- /dev/null
+++ b/Control/Concurrent/Actor/Internal.hs
@@ -0,0 +1,202 @@
+-- |
+-- Module      :  Control.Concurrent.Actor.Internal
+-- Copyright   :  (c) 2014 Forkk
+-- License     :  MIT
+-- Maintainer  :  forkk@forkk.net
+-- Stability   :  experimental
+-- Portability :  GHC only (requires throwTo)
+--
+-- Module exposing more of hactor's internals. Use with caution.
+--
+module Control.Concurrent.Actor.Internal
+    (
+    -- * Types
+      ActorHandle (..)
+    , ActorMessage
+    , ActorM
+    -- * Sending Messages
+    , send
+    , sendIO
+    -- * Receiving Messages
+    , receive
+    , receiveMaybe
+    , receiveSTM
+    -- * Spawning Actors
+    , spawnActor
+    , runActor
+    -- * Getting Information
+    , self
+    , actorThread
+    -- * Internals
+    , ActorContext (..)
+    , MailBox
+    , getContext
+    , getMailBox
+    ) where
+
+import Control.Concurrent
+import Control.Concurrent.STM
+import Control.Monad.Reader
+
+
+-- {{{ Types
+
+-- {{{ Message
+
+-- | The @ActorMessage@ class must be implemented by any type that will be sent
+-- as a message to actors.
+-- Any given type of actor will have one @ActorMessage@ type that is sent to
+-- that actor. This ensures type safety.
+-- Currently this is simply a dummy class with nothing in it, but things may be
+-- added in the future.
+class ActorMessage msg
+
+-- Allow actors that don't take messages.
+instance ActorMessage ()
+
+-- }}}
+
+-- {{{ Handle and context
+
+-- | An @ActorHandle@ acts as a reference to a specific actor.
+data ActorMessage msg => ActorHandle msg = ActorHandle
+    { ahContext     :: ActorContext msg     -- Context for this handle's actor.
+    , ahThread      :: ThreadId             -- The actor's thread ID.
+    }
+
+-- | The @ActorContext@ holds shared information about a given actor.
+-- This is information such as the actor's mail box, the list of actors it's
+-- linked to, etc.
+data ActorMessage msg => ActorContext msg = ActorContext
+    { acMailBox :: MailBox msg  -- Channel for the actor's messages.
+    }
+
+-- | The type for the actor's mail box.
+type MailBox msg = TChan msg
+
+-- }}}
+
+-- }}}
+
+-- | The base actor monad.
+type ActorM msg = ReaderT (ActorContext msg) IO
+
+-- {{{ Get info
+
+-- | Gets a handle to the current actor.
+self :: ActorMessage msg => ActorM msg (ActorHandle msg)
+self = do
+    context <- ask
+    thread <- liftIO $ myThreadId
+    return $ ActorHandle context thread
+
+-- | Retrieves the mail box for the current actor.
+-- This is an internal function and may be dangerous. Use with caution.
+getMailBox :: ActorMessage msg => ActorM msg (MailBox msg)
+getMailBox = asks acMailBox
+
+
+-- | Gets the internal context object for the current actor.
+-- This is an internal function and may be dangerous. Use with caution.
+getContext :: ActorMessage msg => ActorM msg (ActorContext msg)
+getContext = ask
+
+-- }}}
+
+-- {{{ Receiving
+
+-- | Reads a message from the actor's mail box.
+-- If there are no messages, blocks until one is received. If you don't want
+-- this, use @receiveMaybe@ instead.
+receive :: ActorMessage msg => ActorM msg (msg)
+receive = do
+    chan <- getMailBox
+    -- Read from the channel, retrying if there is nothing to read.
+    liftIO $ atomically $ readTChan chan
+
+-- | Reads a message from the actor's mail box.
+-- If there are no messages, returns @Nothing@.
+receiveMaybe :: ActorMessage msg => ActorM msg (Maybe msg)
+receiveMaybe = do
+    chan <- getMailBox
+    liftIO $ atomically $ tryReadTChan chan
+
+-- | An @ActorM@ action which returns an @STM@ action to receive a message.
+receiveSTM :: ActorMessage msg => ActorM msg (STM msg)
+receiveSTM = do
+    chan <- getMailBox
+    return $ readTChan chan
+
+-- }}}
+
+-- {{{ Sending
+
+-- | Sends a message to the given actor handle.
+-- This is secretly just @sendIO@ lifted into an actor monad.
+send :: (ActorMessage msg, ActorMessage msg') =>
+        ActorHandle msg -> msg -> ActorM msg' ()
+send hand msg = liftIO $ sendIO hand msg
+
+-- | Sends a message to the given actor handle from within the IO monad.
+sendIO :: ActorMessage msg => ActorHandle msg -> msg -> IO ()
+sendIO hand msg =
+    atomically $ writeTChan mailBox $ msg
+  where
+    mailBox = handleMailBox hand
+
+-- }}}
+
+-- {{{ Spawning
+
+-- | Internal function for starting actors.
+-- This takes an @ActorM@ action, makes a channel for it, wraps it in exception
+-- handling stuff, and turns it into an IO monad. The function returns a tuple
+-- containing the actor's context and the IO action to execute the actor.
+wrapActor :: ActorMessage msg => ActorM msg () -> IO (IO (), ActorContext msg)
+wrapActor actorAction = do
+    -- TODO: Exception handling.
+    -- First, create a channel for the actor.
+    chan <- atomically newTChan
+    -- Next, create the context and run the ReaderT action.
+    let context = ActorContext chan
+        ioAction = runReaderT actorAction context
+    -- Return the information.
+    return (ioAction, context)
+
+
+-- | Spawns the given actor on another thread and returns a handle to it.
+spawnActor :: ActorMessage msg => ActorM msg () -> IO (ActorHandle msg)
+spawnActor actorAction = do
+    -- Wrap the actor action.
+    (ioAction, context) <- wrapActor actorAction
+    -- Fork the actor's IO action to another thread.
+    thread <- forkIO ioAction
+    -- Return the handle.
+    return $ ActorHandle context thread
+
+-- | Runs the given actor on the current thread.
+-- This function effectively turns the current thread into the actor's thread.
+-- Obviously, this means that this function will block until the actor exits.
+-- You probably want to use this for your "main" actor.
+runActor :: ActorMessage msg => ActorM msg () -> IO ()
+runActor actorAction = do
+    -- Wrap the actor action. We discard the context, because we won't be
+    -- returning a handle to this actor.
+    (ioAction, _) <- wrapActor actorAction
+    -- Execute the IO action on the current thread.
+    ioAction
+
+-- }}}
+
+-- {{{ Utility functions
+
+-- | Gets the mail box for the given handle.
+handleMailBox :: ActorMessage msg => ActorHandle msg -> MailBox msg
+handleMailBox = acMailBox . ahContext
+
+-- | Gets the thread ID for the given actor handle.
+actorThread :: ActorMessage msg => ActorHandle msg -> ThreadId
+actorThread = ahThread
+
+-- }}}
+
diff --git a/hactor.cabal b/hactor.cabal
--- a/hactor.cabal
+++ b/hactor.cabal
@@ -8,7 +8,7 @@
 --       +-+------- breaking API changes
 --       | | +----- non-breaking API additions
 --       | | | +--- code changes with no API change
-version: 1.0.0.1
+version: 1.1.0.0
 
 -- A short (one-line) description of the package.
 synopsis: Lightweight Erlang-style actors for Haskell.
@@ -47,9 +47,20 @@
 -- Constraint on the version of Cabal needed to build this package.
 cabal-version: >=1.20
 
+source-repository head
+  type: git
+  location: https://github.com/Forkk/hactor.git
+
+source-repository this
+  type: git
+  location: https://github.com/Forkk/hactor.git
+  tag: 1.1.0.0
+
 library
   -- Modules exported by the library.
-  exposed-modules: Control.Concurrent.Actor
+  exposed-modules:
+      Control.Concurrent.Actor
+    , Control.Concurrent.Actor.Internal
   
   -- Packages needed in order to build this package.
   build-depends:
