diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,7 @@
+0.1.0.3
+
+* add breadth-first and depth-first search functions.
+
 0.1.0.2
 
 * change `TagPosTreeState` combinators to use `Identity`.
diff --git a/src/Text/HTML/TagSoup/Navigate/Types/TagTreePosState.hs b/src/Text/HTML/TagSoup/Navigate/Types/TagTreePosState.hs
--- a/src/Text/HTML/TagSoup/Navigate/Types/TagTreePosState.hs
+++ b/src/Text/HTML/TagSoup/Navigate/Types/TagTreePosState.hs
@@ -37,15 +37,25 @@
 , liftTagTreePosState
 , putTagTree
 , opticContent
+, findTreeT
+, findTree
+, depthFirstFindTreeT
+, depthFirstFindTree
+, depthFirstFindForestT
+, depthFirstFindForest
+, breadthFirstFindTreeT
+, breadthFirstFindTree
+, breadthFirstFindForestT
+, breadthFirstFindForest
 , findContentUntil
 , findUntil
 , tagBranchLeafText
 ) where
 
-import Control.Applicative(Applicative((<*>), pure), Alternative((<|>), empty), liftA2)
+import Control.Applicative(Applicative((<*>), pure), Alternative((<|>), empty), liftA2, (*>))
 import Control.Category((.))
 import Control.Lens(Rewrapped, Wrapped, Unwrapped, _Wrapped', _Wrapped, iso, view, preview, over, from, _head, _1, _2, _3)
-import Control.Monad(Monad(return, (>>=)))
+import Control.Monad(Monad(return, (>>=)), unless)
 import Control.Monad.Morph(MFunctor(hoist))
 import Control.Monad.Reader.Class(MonadReader(ask, local, reader))
 import Control.Monad.State.Class(MonadState(state, get, put), gets, modify)
@@ -350,6 +360,79 @@
 opticContent k =
   getsTagTreePosState
     (preview (tagTreePosContent . k))
+
+findTreeT ::
+  Monad f =>
+  ((TagTree str -> f Bool) -> TagTreePosStateT str f ())
+  -> (TagTree str -> f Bool)
+  -> TagTreePosStateT str f ()
+findTreeT k pr =
+  do  c <- liftTagTreePosState content
+      z <- lift (pr c)
+      unless z (liftTagTreePosState firstChild *> k pr)
+
+findTree ::
+  ((TagTree str -> Bool) -> TagTreePosState str ())
+  -> (TagTree str -> Bool)
+  -> TagTreePosState str ()
+findTree k pr =
+  findTreeT (\z -> k (runIdentity . z)) (Identity . pr)
+
+depthFirstFindTreeT ::
+  Monad f =>
+  (TagTree str -> f Bool)
+  -> TagTreePosStateT str f ()
+depthFirstFindTreeT =
+  findTreeT depthFirstFindForestT
+
+depthFirstFindTree ::
+  (TagTree str -> Bool)
+  -> TagTreePosState str ()
+depthFirstFindTree pr =
+  depthFirstFindTreeT (Identity . pr)
+
+depthFirstFindForestT ::
+  Monad f =>
+  (TagTree str -> f Bool)
+  -> TagTreePosStateT str f ()
+depthFirstFindForestT pr =
+  do  c <- liftTagTreePosState content
+      z <- lift (pr c)
+      unless z (depthFirstFindTreeT pr <|> (liftTagTreePosState nextSibling *> depthFirstFindForestT pr))
+
+depthFirstFindForest ::
+  (TagTree str -> Bool)
+  -> TagTreePosState str ()
+depthFirstFindForest pr =
+  depthFirstFindForestT (Identity . pr)
+
+breadthFirstFindTreeT ::
+  Monad f =>
+  (TagTree str -> f Bool)
+  -> TagTreePosStateT str f ()
+breadthFirstFindTreeT =
+  findTreeT breadthFirstFindForestT
+  
+breadthFirstFindTree ::
+  (TagTree str -> Bool)
+  -> TagTreePosState str ()
+breadthFirstFindTree pr =
+  breadthFirstFindTreeT (Identity . pr)
+
+breadthFirstFindForestT ::
+  Monad f =>
+  (TagTree str -> f Bool)
+  -> TagTreePosStateT str f ()
+breadthFirstFindForestT pr =
+  do  c <- liftTagTreePosState content
+      z <- lift (pr c)
+      unless z ((liftTagTreePosState nextSibling *> breadthFirstFindForestT pr) <|> breadthFirstFindTreeT pr)
+
+breadthFirstFindForest ::
+  (TagTree str -> Bool)
+  -> TagTreePosState str ()
+breadthFirstFindForest pr =
+  breadthFirstFindForestT (Identity . pr)
 
 findContentUntil ::
   Monad f =>
diff --git a/tagsoup-navigate.cabal b/tagsoup-navigate.cabal
--- a/tagsoup-navigate.cabal
+++ b/tagsoup-navigate.cabal
@@ -1,5 +1,5 @@
 name:                 tagsoup-navigate
-version:              0.1.0.2
+version:              0.1.0.3
 synopsis:             Tagsoup Navigate
 description:          Lenses and data types for navigating tagsoup
 license:              BSD3
