diff --git a/hspec/Main.hs b/hspec/Main.hs
new file mode 100644
--- /dev/null
+++ b/hspec/Main.hs
@@ -0,0 +1,23 @@
+module Main where
+
+import BasePrelude
+import Test.Hspec
+import Data.Text (Text)
+import ListT.Attoparsec
+import Data.Attoparsec.Text
+import qualified ListT.Text
+import qualified ListT
+
+
+main =
+  hspec $ do
+    context "sample 1" $ do
+      let textStream = ListT.Text.stream 2 "abcdefg"
+      context "result" $ do
+        result <- flip consumeOne textStream $ string "abc" *> string "de" *> char 'f'
+        context "head" $ do
+          head <- return $ fmap fst result
+          it "should be correct" $ shouldBe head (Right 'f')
+        context "remainder" $ do
+          remainder <- traverse ListT.toList $ fmap snd result
+          it "should be correct" $ shouldBe remainder (Right ["g"])
diff --git a/library/ListT/Attoparsec.hs b/library/ListT/Attoparsec.hs
--- a/library/ListT/Attoparsec.hs
+++ b/library/ListT/Attoparsec.hs
@@ -7,6 +7,7 @@
 import Data.Text (Text)
 import ListT
 import qualified Data.Attoparsec.Text as P
+import qualified Data.Text as T
 
 
 -- |
@@ -36,4 +37,27 @@
         P.Fail _ contexts message -> 
           lift $ EitherT $ return $ Left $ Error message contexts
 
-
+-- |
+-- Consume only as much input as needed to run the provided parser once.
+-- Results in either a failure or the parsed result and the leftover stream.
+-- The failure value of 'Nothing' implies the end of input.
+consumeOne :: Monad m => P.Parser a -> ListT m Text -> m (Either Error (a, ListT m Text))
+consumeOne =
+  \p -> loop (P.parse p)
+  where
+    loop parse stream =
+      uncons stream >>= \case
+        Nothing -> parseCons ("", mempty)
+        Just pair -> parseCons pair
+      where
+        parseCons (chunk, streamRemainder) =
+          case parse chunk of
+            P.Done chunk' result ->
+              return $ Right $ (result, stream')
+              where
+                stream' =
+                  bool (cons chunk') id (T.null chunk') streamRemainder
+            P.Partial parse' ->
+              loop parse' streamRemainder
+            P.Fail _ contexts message ->
+              return $ Left $ Error message contexts
diff --git a/list-t-attoparsec.cabal b/list-t-attoparsec.cabal
--- a/list-t-attoparsec.cabal
+++ b/list-t-attoparsec.cabal
@@ -1,7 +1,7 @@
 name:
   list-t-attoparsec
 version:
-  0.3.0.0
+  0.3.1.0
 synopsis:
   An "attoparsec" adapter for "list-t"
 category:
@@ -39,8 +39,6 @@
   other-modules:
   exposed-modules:
     ListT.Attoparsec
-  ghc-options:
-    -funbox-strict-fields
   default-extensions:
     Arrows, BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, ImpredicativeTypes, LambdaCase, LiberalTypeSynonyms, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators
   default-language:
@@ -52,3 +50,28 @@
     either == 4.*,
     transformers >= 0.3 && < 0.5,
     base-prelude >= 0.1.19 && < 0.2
+
+
+test-suite hspec
+  type:
+    exitcode-stdio-1.0
+  hs-source-dirs:
+    hspec
+  main-is:
+    Main.hs
+  ghc-options:
+    -threaded
+    "-with-rtsopts=-N"
+  default-extensions:
+    Arrows, BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, ImpredicativeTypes, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators, UnboxedTuples
+  default-language:
+    Haskell2010
+  build-depends:
+    hspec == 2.1.*,
+    list-t-attoparsec,
+    list-t-text == 0.2.*,
+    list-t,
+    attoparsec,
+    either,
+    text,
+    base-prelude
