diff --git a/Sound/OpenSoundControl.hs b/Sound/OpenSoundControl.hs
--- a/Sound/OpenSoundControl.hs
+++ b/Sound/OpenSoundControl.hs
@@ -1,21 +1,35 @@
--- | hosc implements a subset of the Open Sound Control byte protocol.
---   The protocol is documented at <http://opensoundcontrol.org/>.
-module Sound.OpenSoundControl (module O
+-- | An implementation of a subset of the /Open Sound Control/ byte
+-- protocol, documented at <http://opensoundcontrol.org/>.
+--
+-- For the most part this top-level module is the only import
+-- required.  It provides the 'Datum' and 'OSC' types, 'encodeOSC' and
+-- 'decodeOSC' functions, basic 'UDP' and 'TCP' 'Transport' layers,
+-- and basic temporal operations 'utcr' to access the current time and
+-- 'pauseThread' to delay the current thread.
+--
+-- > let o = Bundle immediately [Message "/g_free" [Int 0]]
+-- > in decodeOSC (encodeOSC o) == o
+module Sound.OpenSoundControl (module Sound.OpenSoundControl.Type
+                              ,module Sound.OpenSoundControl.Time
+                              ,module Sound.OpenSoundControl.Transport
+                              ,module Sound.OpenSoundControl.Transport.UDP
+                              ,module Sound.OpenSoundControl.Transport.TCP
                               ,C.encodeOSC,C.decodeOSC
                               ,openUDP,udpServer
                               ,openTCP,tcpServer) where
 
-import qualified Sound.OpenSoundControl.Coding.Decode.Binary as C
-import qualified Sound.OpenSoundControl.Coding.Encode.Builder as C
-import Sound.OpenSoundControl.Type as O
-import Sound.OpenSoundControl.Time as O
-import Sound.OpenSoundControl.Transport as O
-import Sound.OpenSoundControl.Transport.UDP as O
-import Sound.OpenSoundControl.Transport.TCP as O
+import Sound.OpenSoundControl.Coding.Decode.Binary as C
+import Sound.OpenSoundControl.Coding.Encode.Builder as C
+import Sound.OpenSoundControl.Type
+import Sound.OpenSoundControl.Time
+import Sound.OpenSoundControl.Transport
+import Sound.OpenSoundControl.Transport.UDP
+import Sound.OpenSoundControl.Transport.TCP
 
 -- | Make a UDP connection.
 --
--- > withTransport (openUDP "127.0.0.1" 57110) (\fd -> recvT 0.5 fd >>= print)
+-- > let t = openUDP "127.0.0.1" 57110
+-- > in withTransport t (\fd -> recvT 0.5 fd >>= print)
 openUDP :: String -> Int -> IO UDP
 openUDP = openUDP' (C.encodeOSC,C.decodeOSC)
 
diff --git a/Sound/OpenSoundControl/Coding.hs b/Sound/OpenSoundControl/Coding.hs
--- a/Sound/OpenSoundControl/Coding.hs
+++ b/Sound/OpenSoundControl/Coding.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE FlexibleInstances,TypeSynonymInstances #-}
 -- | A type-class to provide coding operations to different data types
 --   using the same function names.
-module Sound.OpenSoundControl.Coding (Coding(..) ) where
+module Sound.OpenSoundControl.Coding (Coding(..),Coder) where
 
 import qualified Data.ByteString as S
 import qualified Data.ByteString.Lazy as B
@@ -28,3 +28,6 @@
 instance Coding String where
     encodeOSC = C.unpack . encodeOSC
     decodeOSC = decodeOSC . C.pack
+
+-- | An 'encodeOSC' and 'decodeOSC' pair over 'B.ByteString'.
+type Coder = (OSC -> B.ByteString,B.ByteString -> OSC)
diff --git a/Sound/OpenSoundControl/Coding/Decode/Base.hs b/Sound/OpenSoundControl/Coding/Decode/Base.hs
--- a/Sound/OpenSoundControl/Coding/Decode/Base.hs
+++ b/Sound/OpenSoundControl/Coding/Decode/Base.hs
@@ -79,6 +79,9 @@
     in Bundle timeStamp ms
 
 -- | Decode an OSC packet.
+--
+-- > let b = B.pack [47,103,95,102,114,101,101,0,44,105,0,0,0,0,0,0]
+-- > in decodeOSC b == Message "/g_free" [Int 0]
 decodeOSC :: B.ByteString -> OSC
 decodeOSC b =
     if bundleHeader `B.isPrefixOf` b
diff --git a/Sound/OpenSoundControl/Coding/Decode/Binary.hs b/Sound/OpenSoundControl/Coding/Decode/Binary.hs
--- a/Sound/OpenSoundControl/Coding/Decode/Binary.hs
+++ b/Sound/OpenSoundControl/Coding/Decode/Binary.hs
@@ -7,7 +7,7 @@
 import Data.Binary.Get
 import qualified Data.Binary.IEEE754 as I
 import qualified Data.ByteString as S
-import qualified Data.ByteString.Lazy as B
+import qualified Data.ByteString.Lazy as L
 import qualified Data.ByteString.Lazy.Char8 as C
 import Data.Int (Int32)
 import Data.Word (Word32)
@@ -21,7 +21,7 @@
 isolate n m = do
     s <- get_bytes n
     let (a, s', _) = runGetState m s 0
-    if B.null s'
+    if L.null s'
         then return a
         else fail "isolate: not all bytes consumed"
 
@@ -33,14 +33,14 @@
 get_string :: Get String
 get_string = do
     s <- getLazyByteStringNul
-    skip (fromIntegral (align (B.length s + 1)))
+    skip (fromIntegral (align (L.length s + 1)))
     return $ C.unpack s
 
 -- | Get binary data prefixed by byte count.
-get_bytes :: Word32 -> Get B.ByteString
+get_bytes :: Word32 -> Get L.ByteString
 get_bytes n = do
     b <- getLazyByteString (fromIntegral n)
-    if n /= fromIntegral (B.length b)
+    if n /= fromIntegral (L.length b)
         then fail "get_bytes: end of stream"
         else skip (fromIntegral (align n))
     return b
@@ -75,7 +75,7 @@
 -- | Get an OSC packet.
 get_packet :: Get OSC
 get_packet = do
-    h <- uncheckedLookAhead (B.length bundleHeader)
+    h <- uncheckedLookAhead (L.length bundleHeader)
     if h == bundleHeader
         then get_bundle
         else get_message
@@ -93,7 +93,7 @@
 
 get_bundle :: Get OSC
 get_bundle = do
-    skip (fromIntegral (B.length bundleHeader))
+    skip (fromIntegral (L.length bundleHeader))
     t <- NTPi <$> getWord64be
     ps <- get_packet_seq
     return $ Bundle t ps
@@ -103,11 +103,14 @@
 getOSC = get_packet
 
 -- | Decode an OSC packet from a lazy ByteString.
-decodeOSC :: B.ByteString -> OSC
+--
+-- > let b = L.pack [47,103,95,102,114,101,101,0,44,105,0,0,0,0,0,0]
+-- > in decodeOSC b == Message "/g_free" [Int 0]
+decodeOSC :: L.ByteString -> OSC
 {-# INLINE decodeOSC #-}
 decodeOSC = runGet getOSC
 
 -- | Decode an OSC packet from a strict ByteString.
 decodeOSC' :: S.ByteString -> OSC
 {-# INLINE decodeOSC' #-}
-decodeOSC' = runGet getOSC . B.fromChunks . (:[])
+decodeOSC' = runGet getOSC . L.fromChunks . (:[])
diff --git a/Sound/OpenSoundControl/Coding/Encode/Builder.hs b/Sound/OpenSoundControl/Coding/Encode/Builder.hs
--- a/Sound/OpenSoundControl/Coding/Encode/Builder.hs
+++ b/Sound/OpenSoundControl/Coding/Encode/Builder.hs
@@ -64,6 +64,9 @@
 buildOSC (Bundle (UTCr t) l) = build_bundle_ntpi (utcr_ntpi t) l
 
 -- | Encode an OSC packet to a lazy ByteString.
+--
+-- > let b = L.pack [47,103,95,102,114,101,101,0,44,105,0,0,0,0,0,0]
+-- > in encodeOSC (Message "/g_free" [Int 0]) == b
 encodeOSC :: OSC -> L.ByteString
 {-# INLINE encodeOSC #-}
 encodeOSC = B.toLazyByteString . buildOSC
diff --git a/Sound/OpenSoundControl/Time.hs b/Sound/OpenSoundControl/Time.hs
--- a/Sound/OpenSoundControl/Time.hs
+++ b/Sound/OpenSoundControl/Time.hs
@@ -7,10 +7,12 @@
 import Data.Word
 import qualified Data.Time as T
 
+-- * Temporal types
+
 -- | Type for integer representation of NTP time.
 type NTPi = Word64
 
--- | Time is represented in either UTC or NTP form.  The NTP form may
+-- | Time is represented in either @UTC@ or @NTP@ form.  The @NTP@ form may
 --   be either integral or real.
 data Time = UTCr Double | NTPr Double | NTPi NTPi
             deriving (Read, Show)
@@ -19,7 +21,7 @@
     a == b = as_ntpi a == as_ntpi b
     a /= b = as_ntpi a /= as_ntpi b
 
--- | Coerce to NTPi form.
+-- | Coerce 'Time' to integral @NTP@ form.
 as_ntpi :: Time -> NTPi
 as_ntpi x =
     case x of
@@ -27,7 +29,7 @@
       NTPr t -> ntpr_ntpi t
       NTPi t -> t
 
--- | Coerce to UTCr form.
+-- | Coerce 'Time' to real-valued @UTC@ form.
 as_utcr :: Time -> Double
 as_utcr x =
     case x of
@@ -44,27 +46,27 @@
           (NTPi p',NTPi q') -> compare p' q'
           _ -> compare (as_ntpi p) (as_ntpi q)
 
--- | Convert a real-valued NTP timestamp to an NTP timestamp.
+-- | Convert a real-valued NTP timestamp to an 'NTPi' timestamp.
 ntpr_ntpi :: Double -> NTPi
 ntpr_ntpi t = round (t * 2^(32::Int))
 
--- | Convert an NTP timestamp to a real-valued NTP timestamp.
+-- | Convert an 'NTPi' timestamp to a real-valued NTP timestamp.
 ntpi_ntpr :: NTPi -> Double
 ntpi_ntpr t = fromIntegral t / 2^(32::Int)
 
--- | Convert UTC timestamp to NTP timestamp.
+-- | Convert a real-valued UTC timestamp to an 'NTPi' timestamp.
 utcr_ntpi :: Double -> NTPi
 utcr_ntpi t =
     let secdif = (70 * 365 + 17) * 24 * 60 * 60
     in ntpr_ntpi (t + secdif)
 
--- | Convert NTP timestamp to UTC timestamp.
+-- | Convert a real-valued NTP timestamp to a real-valued UTC timestamp.
 ntpr_utcr :: Double -> Double
 ntpr_utcr t =
     let secdif = (70 * 365 + 17) * 24 * 60 * 60
     in t - secdif
 
--- | Convert NTP timestamp to UTC timestamp.
+-- | Convert an 'NTPi' timestamp to a real-valued UTC timestamp.
 ntpi_utcr :: NTPi -> Double
 ntpi_utcr = ntpr_utcr . ntpi_ntpr
 
@@ -75,35 +77,41 @@
         s = T.secondsToDiffTime 0
     in T.UTCTime d s
 
--- | Read current UTCr timestamp.
+-- | Constant indicating the bundle is to be executed immediately.
+immediately :: Time
+immediately = NTPi 1
+
+-- * Clock operations
+
+-- | Read current real-valued @UTC@ timestamp.
 utcr :: IO Double
 utcr = do
   t <- T.getCurrentTime
   return (realToFrac (T.diffUTCTime t utc_base))
 
--- | Read current NTP timestamp.
+-- | Read current 'NTPi' timestamp.
 ntpi :: IO NTPi
 ntpi = liftM utcr_ntpi utcr
 
--- | The pauseThread limit (in seconds).  Values larger than this
---   require a different thread delay mechanism, see sleepThread.  The
---   value is the number of microseconds in maxBound::Int.
+-- | The 'pauseThread' limit (in seconds).  Values larger than this
+-- require a different thread delay mechanism, see 'sleepThread'.  The
+-- value is the number of microseconds in @maxBound::Int@.
 pauseThreadLimit :: Double
 pauseThreadLimit = fromIntegral (maxBound::Int) / 1e6
 
 -- | Pause current thread for the indicated duration (in seconds), see
---   pauseThreadLimit.  Note also that this function does not attempt
---   pauses less than 1e-4.
+--   'pauseThreadLimit'.  Note also that this function does not
+--   attempt pauses less than @1e-4@.
 pauseThread :: Double -> IO ()
 pauseThread n = when (n > 1e-4) (threadDelay (floor (n * 1e6)))
 
--- | Pause current thread until the given utcr time, see
---   pauseThreadLimit.
+-- | Pause current thread until the given real-valued @UTC@ time, see
+-- 'pauseThreadLimit'.
 pauseThreadUntil :: Double -> IO ()
 pauseThreadUntil t = pauseThread . (t -) =<< utcr
 
 -- | Sleep current thread for the indicated duration (in seconds).
---   Divides long sleeps into parts smaller than pauseThreadLimit.
+--   Divides long sleeps into parts smaller than 'pauseThreadLimit'.
 sleepThread :: Double -> IO ()
 sleepThread n =
     if n >= pauseThreadLimit
@@ -111,11 +119,7 @@
          in pauseThread n >> sleepThread (n - n')
     else pauseThread n
 
--- | Sleep current thread until the given utcr time.  Divides long
---   sleeps into parts smaller than pauseThreadLimit.
+-- | Sleep current thread until the given real-valued @UTC@ time.
+-- Divides long sleeps into parts smaller than 'pauseThreadLimit'.
 sleepThreadUntil :: Double -> IO ()
 sleepThreadUntil t = sleepThread . (t -) =<< utcr
-
--- | Execute the bundle immediately.
-immediately :: Time
-immediately = NTPi 1
diff --git a/Sound/OpenSoundControl/Transport/TCP.hs b/Sound/OpenSoundControl/Transport/TCP.hs
--- a/Sound/OpenSoundControl/Transport/TCP.hs
+++ b/Sound/OpenSoundControl/Transport/TCP.hs
@@ -6,6 +6,7 @@
 import qualified Data.ByteString.Lazy as B
 import Control.Monad
 import Network
+import Sound.OpenSoundControl.Coding
 import Sound.OpenSoundControl.Coding.Byte
 import Sound.OpenSoundControl.Transport
 import Sound.OpenSoundControl.Type
@@ -27,8 +28,6 @@
          b1 <- B.hGet fd (fromIntegral (decode_u32 b0))
          return (dec b1)
    close (TCP _ _ fd) = hClose fd
-
-type Coder = (OSC -> B.ByteString,B.ByteString -> OSC)
 
 -- | Make a TCP connection using specified coder.
 openTCP' :: Coder -> String -> Int -> IO TCP
diff --git a/Sound/OpenSoundControl/Transport/UDP.hs b/Sound/OpenSoundControl/Transport/UDP.hs
--- a/Sound/OpenSoundControl/Transport/UDP.hs
+++ b/Sound/OpenSoundControl/Transport/UDP.hs
@@ -10,6 +10,7 @@
 import qualified Network.Socket as N
 import qualified Network.Socket.ByteString as C (sendTo,recvFrom)
 import qualified Network.Socket.ByteString.Lazy as C (send,recv)
+import Sound.OpenSoundControl.Coding
 import Sound.OpenSoundControl.Transport
 import Sound.OpenSoundControl.Type
 
@@ -26,8 +27,6 @@
    send  (UDP enc _ fd) msg = C.send fd (enc msg) >> return ()
    recv  (UDP _ dec fd) = liftM dec (C.recv fd 8192)
    close (UDP _ _ fd) = N.sClose fd
-
-type Coder = (OSC -> B.ByteString,B.ByteString -> OSC)
 
 -- | Make a UDP connection with specified coder.
 openUDP' :: Coder -> String -> Int -> IO UDP
diff --git a/Sound/OpenSoundControl/Type.hs b/Sound/OpenSoundControl/Type.hs
--- a/Sound/OpenSoundControl/Type.hs
+++ b/Sound/OpenSoundControl/Type.hs
@@ -1,9 +1,9 @@
 -- | Alegbraic data types for OSC datum and packets.
-module Sound.OpenSoundControl.Type ( OSC(..)
-                                   , Datum(..)
-                                   , message
-                                   , bundle
-                                   , tag ) where
+module Sound.OpenSoundControl.Type (OSC(..)
+                                   ,Datum(..)
+                                   ,message
+                                   ,bundle
+                                   ,tag) where
 
 import qualified Data.ByteString.Lazy as B
 import Data.Word
@@ -17,15 +17,15 @@
            | Blob B.ByteString
            | TimeStamp Time
            | Midi (Word8,Word8,Word8,Word8)
-             deriving (Eq, Read, Show)
+             deriving (Eq,Read,Show)
 
 -- | An OSC packet.
 data OSC = Message String [Datum]
          | Bundle Time [OSC]
-           deriving (Eq, Read, Show)
+           deriving (Eq,Read,Show)
 
 -- | OSC bundles can be ordered (time ascending).  Bundles and
---   messages compare EQ.
+--   messages compare 'EQ'.
 instance Ord OSC where
     compare (Bundle a _) (Bundle b _) = compare a b
     compare _ _ = EQ
@@ -42,21 +42,17 @@
       TimeStamp _ -> 't'
       Midi _ -> 'm'
 
--- | Bundle constructor.
---
--- Signals an error when @xs@ is empty.
+-- | Bundle constructor. It is an 'error' if the 'OSC' list is empty.
 bundle :: Time -> [OSC] -> OSC
 bundle t xs =
     case xs of
       [] -> error "bundle: empty?"
       _ -> Bundle t xs
 
--- | Message constructor
---
--- Signals an error when the address @a@ doesn't conform to the OSC
--- specification.
+-- | Message constructor.  It is an 'error' if the address doesn't
+-- conform to the OSC specification.
 message :: String -> [Datum] -> OSC
 message a xs =
     case a of
-      ('/':_) -> Message a xs
+      '/':_ -> Message a xs
       _ -> error "message: ill-formed address"
diff --git a/hosc.cabal b/hosc.cabal
--- a/hosc.cabal
+++ b/hosc.cabal
@@ -1,9 +1,9 @@
 Name:              hosc
-Version:           0.10.1
+Version:           0.11
 Synopsis:          Haskell Open Sound Control
-Description:       hosc provides Sound.OpenSoundControl, a haskell
-                   module implementing a subset of the Open Sound
-                   Control byte protocol.
+Description:       @hosc@ provides "Sound.OpenSoundControl", an
+                   implementation of a subset of the /Open Sound Control/
+                   byte protocol documented at <http://opensoundcontrol.org/>.
 License:           GPL
 Category:          Sound
 Copyright:         (c) Rohan Drape, Stefan Kersten and others, 2006-2011
@@ -11,7 +11,7 @@
 Maintainer:        rd@slavepianos.org
 Stability:         Experimental
 Homepage:          http://slavepianos.org/rd/?t=hosc
-Tested-With:       GHC == 7.0.4
+Tested-With:       GHC == 7.2.2
 Build-Type:        Simple
 Cabal-Version:     >= 1.8
 Data-Files:        README
