diff --git a/Changelog.md b/Changelog.md
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,5 +1,9 @@
 # Changelog for net-mqtt
 
+## 0.8.0.1
+
+Added an `Arbitrary` instance for `Filter`.
+
 ## 0.8.0.0
 
 The `Topic` and `Filter` types are now `newtype` wrappers around Text
diff --git a/app/mqtt-watch/Main.hs b/app/mqtt-watch/Main.hs
--- a/app/mqtt-watch/Main.hs
+++ b/app/mqtt-watch/Main.hs
@@ -17,12 +17,12 @@
 import qualified Data.Text.IO               as TIO
 import           Data.Word                  (Word32)
 import           Network.MQTT.Client
-import           Network.MQTT.Topic         (Filter, Topic, mkFilter, unTopic)
+import           Network.MQTT.Topic         (Filter, mkFilter, unTopic)
 import           Network.MQTT.Types         (ConnACKFlags (..), SessionReuse (..), qosFromInt)
 import           Network.URI
 import           Options.Applicative        (Parser, argument, auto, eitherReader, execParser, fullDesc, help, helper,
                                              info, long, maybeReader, metavar, option, progDesc, short, showDefault,
-                                             some, str, switch, value, (<**>))
+                                             some, switch, value, (<**>))
 import           System.IO                  (stdout)
 import           Text.Read                  (readMaybe)
 
diff --git a/net-mqtt.cabal b/net-mqtt.cabal
--- a/net-mqtt.cabal
+++ b/net-mqtt.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: b407b40c8336bc1b3e8490c3097a2bf78450622686c0e5c0e621e33675b4829d
+-- hash: 5a165eeed76406b35cd868b291e467af93ca4b8ac8a9da0670c73f3c8999b4c6
 
 name:           net-mqtt
-version:        0.8.0.0
+version:        0.8.0.1
 synopsis:       An MQTT Protocol Implementation.
 description:    Please see the README on GitHub at <https://github.com/dustin/mqtt-hs#readme>
 category:       Network
diff --git a/src/Network/MQTT/Arbitrary.hs b/src/Network/MQTT/Arbitrary.hs
--- a/src/Network/MQTT/Arbitrary.hs
+++ b/src/Network/MQTT/Arbitrary.hs
@@ -29,7 +29,7 @@
 import           Data.Maybe            (mapMaybe)
 import           Data.Text             (Text)
 import qualified Data.Text             as Text
-import           Network.MQTT.Topic    (Filter, Topic, mkFilter, mkTopic, unTopic)
+import           Network.MQTT.Topic    (Filter, Topic, mkFilter, mkTopic, unTopic, unFilter)
 import           Network.MQTT.Types    as MT
 import           Test.QuickCheck       as QC
 
@@ -257,3 +257,20 @@
         clean []      = []
         clean ("#":_) = ["#"]
         clean (x:xs)  = x : clean xs
+
+-- | Generate an arbitrary Filter from the given alphabet with lengths
+-- of segments and the segment count specified by the given ranges.
+-- Segments may contain wildcards.
+arbitraryFilter :: [Char] -> (Int,Int) -> (Int,Int) -> Gen Filter
+arbitraryFilter alphabet seglen nsegs = someSegs `suchThatMap` (mkFilter . Text.intercalate "/")
+    where someSegs = choose nsegs >>= flip vectorOf aSeg
+          aSeg = oneof [
+            pure "+", pure "#",
+            choose seglen >>= arbitraryTopicSegment alphabet
+            ]
+
+instance Arbitrary Filter where
+  arbitrary = arbitraryFilter ['a'..'z'] (1,6) (1,6)
+
+  shrink (unFilter -> x) = mapMaybe (mkFilter . Text.intercalate "/") . shrinkList shrinkWord $ Text.splitOn "/" x
+    where shrinkWord = fmap Text.pack . shrink . Text.unpack
diff --git a/src/Network/MQTT/Client.hs b/src/Network/MQTT/Client.hs
--- a/src/Network/MQTT/Client.hs
+++ b/src/Network/MQTT/Client.hs
@@ -68,7 +68,7 @@
 import           System.IO.Error            (catchIOError, isEOFError)
 import           System.Timeout             (timeout)
 
-import           Network.MQTT.Topic         (Filter, Topic, mkFilter, mkTopic, unFilter, unTopic)
+import           Network.MQTT.Topic         (Filter, Topic, mkTopic, unFilter, unTopic)
 import           Network.MQTT.Types         as T
 
 data ConnState = Starting
@@ -438,7 +438,7 @@
 
         resolve p@PublishRequest{..} = do
           topic <- resolveTopic (foldr aliasID Nothing _pubProps)
-          pure p{_pubTopic=textToBL (unTopic topic)}
+          pure p{_pubTopic=topicToBL topic}
 
           where
             aliasID (PropTopicAlias x) _ = Just x
@@ -496,12 +496,15 @@
 blToText :: BL.ByteString -> Text
 blToText = TE.decodeUtf8 . BL.toStrict
 
+topicToBL :: Topic -> BL.ByteString
+topicToBL = textToBL . unTopic
+
+filterToBL :: Filter -> BL.ByteString
+filterToBL = textToBL . unFilter
+
 blToTopic :: BL.ByteString -> Topic
 blToTopic = fromJust . mkTopic . blToText
 
-blToFilter :: BL.ByteString -> Filter
-blToFilter = fromJust . mkFilter . blToText
-
 reservePktID :: MQTTClient -> [DispatchType] -> STM (TChan MQTTPkt, Word16)
 reservePktID c@MQTTClient{..} dts = do
   checkConnected c
@@ -540,7 +543,7 @@
   let (SubACKPkt (SubscribeResponse _ rs aprops)) = r
   pure (rs, aprops)
 
-    where ls' = map (first (textToBL . unFilter)) ls
+    where ls' = map (first filterToBL) ls
 
 -- | Unsubscribe from a list of topic filters.
 --
@@ -551,7 +554,7 @@
 -- should know about.
 unsubscribe :: MQTTClient -> [Filter] -> [Property] -> IO ([UnsubStatus], [Property])
 unsubscribe c@MQTTClient{..} ls props = do
-  (UnsubACKPkt (UnsubscribeResponse _ rsn rprop)) <- sendAndWait c DUnsubACK (\pid -> UnsubscribePkt $ UnsubscribeRequest pid (map (textToBL . unFilter) ls) props)
+  (UnsubACKPkt (UnsubscribeResponse _ rsn rprop)) <- sendAndWait c DUnsubACK (\pid -> UnsubscribePkt $ UnsubscribeRequest pid (map filterToBL ls) props)
   pure (rprop, rsn)
 
 -- | Publish a message (QoS 0).
@@ -584,7 +587,7 @@
                                              _pubQoS = q,
                                              _pubPktID = pid,
                                              _pubRetain = r,
-                                             _pubTopic = textToBL (unTopic t),
+                                             _pubTopic = topicToBL t,
                                              _pubBody = m,
                                              _pubProps = props}
 
@@ -630,7 +633,7 @@
 mkLWT t m r = T.LastWill{
   T._willRetain=r,
   T._willQoS=QoS0,
-  T._willTopic = textToBL (unTopic t),
+  T._willTopic = topicToBL t,
   T._willMsg=m,
   T._willProps=mempty
   }
