diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -58,8 +58,8 @@
 * CSVeable is parameterized on both a stream type and a target CSV row type.
 * There are 2 basic row types and they implement *exactly* the same operations,
   so you can chose the right one for the job at hand:
-  - type MapRow t = Map t t
-  - type Row t = [t]
+  - `type MapRow t = Map t t`
+  - `type Row t = [t]`
 * You basically use the Conduits defined in this library to do the
   parsing from a CSV stream and rendering back into a CSV stream.
 * Use the full flexibility and modularity of conduits for sources and sinks.
@@ -76,46 +76,48 @@
 
 #### Example #1: Basics Using Convenience API
 
-    {-# LANGUAGE OverloadedStrings #-}
+```haskell
+{-# LANGUAGE OverloadedStrings #-}
 
-    import Data.Conduit
-    import Data.Conduit.Binary
-    import Data.Conduit.List as CL
-    import Data.CSV.Conduit
-    import Data.Text (Text)
-    
-    -- Just reverse te columns
-    myProcessor :: Monad m => Conduit (Row Text) m (Row Text)
-    myProcessor = CL.map reverse
-    
-    test :: IO ()
-    test = runResourceT $ 
-      transformCSV defCSVSettings 
-                   (sourceFile "input.csv") 
-                   myProcessor
-                   (sinkFile "output.csv")
+import Data.Conduit
+import Data.Conduit.Binary
+import Data.Conduit.List as CL
+import Data.CSV.Conduit
+import Data.Text (Text)
 
+-- Just reverse te columns
+myProcessor :: Monad m => Conduit (Row Text) m (Row Text)
+myProcessor = CL.map reverse
 
+test :: IO ()
+test = runResourceT $ 
+  transformCSV defCSVSettings 
+               (sourceFile "input.csv") 
+               myProcessor
+               (sinkFile "output.csv")
+```
+
 #### Example #2: Basics Using Conduit API
 
-    {-# LANGUAGE OverloadedStrings #-}
+```haskell
+{-# LANGUAGE OverloadedStrings #-}
 
-    import Data.Conduit
-    import Data.Conduit.Binary
-    import Data.CSV.Conduit
-    import Data.Text (Text)
+import Data.Conduit
+import Data.Conduit.Binary
+import Data.CSV.Conduit
+import Data.Text (Text)
 
-    myProcessor :: Monad m => Conduit (Row Text) m (Row Text)
-    myProcessor = awaitForever $ yield
-    
-    -- Let's simply stream from a file, parse the CSV, reserialize it
-    -- and push back into another file.
-    test :: IO ()
-    test = runResourceT $ 
-      sourceFile "test/BigFile.csv" $= 
-      intoCSV defCSVSettings $=
-      myProcessor $=
-      fromCSV defCSVSettings $$
-      sinkFile "test/BigFileOut.csv"
+myProcessor :: Monad m => Conduit (Row Text) m (Row Text)
+myProcessor = awaitForever $ yield
 
+-- Let's simply stream from a file, parse the CSV, reserialize it
+-- and push back into another file.
+test :: IO ()
+test = runResourceT $ 
+  sourceFile "test/BigFile.csv" $= 
+  intoCSV defCSVSettings $=
+  myProcessor $=
+  fromCSV defCSVSettings $$
+  sinkFile "test/BigFileOut.csv"
+```
 
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,2 +1,7 @@
+0.6.8
+* Haddocks improvements
+* Fix inlining and specialization rules around formatDecimal
+* Updates to permit newest conduit/resourcet packages
+
 0.6.7
 * Fix build for GHC 8.0.1
diff --git a/csv-conduit.cabal b/csv-conduit.cabal
--- a/csv-conduit.cabal
+++ b/csv-conduit.cabal
@@ -1,5 +1,5 @@
 Name:                csv-conduit
-Version:             0.6.7
+Version:             0.6.8
 Synopsis:            A flexible, fast, conduit-based CSV parser library for Haskell.
 Homepage:            http://github.com/ozataman/csv-conduit
 License:             BSD3
@@ -59,8 +59,11 @@
   changelog.md
   test/test.csv
   test/Test.hs
-  test/Bench.hs
 
+flag lib-Werror
+  default: False
+  manual: True
+
 library
   exposed-modules:
       Data.CSV.Conduit
@@ -72,14 +75,17 @@
       Data.CSV.Conduit.Conversion.Internal
       Data.CSV.Conduit.Monoid
   ghc-options: -Wall -funbox-strict-fields
+  if flag(lib-Werror)
+    ghc-options: -Werror
   hs-source-dirs: src
   build-depends:
       attoparsec             >= 0.10
     , base                   >= 4 && < 5
     , bytestring
-    , conduit                >= 1.0 && < 2.0
+    , conduit                >= 1.2.8 && < 2.0
     , conduit-extra
     , containers             >= 0.3
+    , exceptions             >= 0.3
     , monad-control
     , text
     , data-default
@@ -92,7 +98,6 @@
     , mmorph
     , primitive
     , resourcet              >= 1.1.2.1
-  ghc-prof-options: -fprof-auto
 
   if impl(ghc >= 7.2.1)
     cpp-options: -DGENERICS
@@ -103,6 +108,8 @@
   type: exitcode-stdio-1.0
   main-is: Test.hs
   ghc-options: -Wall
+  if flag(lib-Werror)
+    ghc-options: -Werror
   hs-source-dirs: test
   build-depends:
       base >= 4 && < 5
@@ -119,29 +126,7 @@
     , mtl
     , primitive
 
-flag bench
-  default: False
-  manual: True
 
-executable bench
-  main-is: Bench.hs
-  if flag(bench)
-    buildable: True
-  else
-    buildable: False
-  ghc-options: -Wall
-  hs-source-dirs: test
-  build-depends:
-      base >= 4 && < 5
-    , bytestring
-    , containers >= 0.3
-    , csv-conduit
-    , vector
-    , directory
-    , text
-    , transformers
-    , mtl
-    , primitive
-
-  ghc-options: -rtsopts
-  ghc-prof-options: -rtsopts -caf-all -auto-all
+source-repository head
+  type:     git
+  location: git://github.com/ozataman/csv-conduit.git
diff --git a/src/Data/CSV/Conduit.hs b/src/Data/CSV/Conduit.hs
--- a/src/Data/CSV/Conduit.hs
+++ b/src/Data/CSV/Conduit.hs
@@ -1,9 +1,11 @@
 {-# LANGUAGE BangPatterns          #-}
+{-# LANGUAGE CPP                   #-}
 {-# LANGUAGE FlexibleContexts      #-}
 {-# LANGUAGE FlexibleInstances     #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE OverloadedStrings     #-}
 {-# LANGUAGE RankNTypes            #-}
+{-# LANGUAGE ScopedTypeVariables   #-}
 {-# LANGUAGE TypeSynonymInstances  #-}
 {-# LANGUAGE UndecidableInstances  #-}
 
@@ -32,12 +34,12 @@
 
 -------------------------------------------------------------------------------
 import           Control.Exception
-import           Control.Monad.Morph
+import           Control.Monad.Catch.Pure           (CatchT)
+import           Control.Monad.Catch.Pure           (runCatchT)
+import           Control.Monad.Except
 import           Control.Monad.Primitive
 import           Control.Monad.ST
-import           Control.Monad.Trans
 import           Control.Monad.Trans.Resource       (MonadResource, MonadThrow,
-                                                     runExceptionT,
                                                      runResourceT)
 import           Data.Attoparsec.Types              (Parser)
 import qualified Data.ByteString                    as B
@@ -57,6 +59,7 @@
 import qualified Data.Vector                        as V
 import qualified Data.Vector.Generic                as GV
 import qualified Data.Vector.Generic.Mutable        as GMV
+import           Data.Void                          (Void)
 import           System.IO
 -------------------------------------------------------------------------------
 import           Data.CSV.Conduit.Conversion        (FromNamedRecord (..),
@@ -111,11 +114,11 @@
 -- >myProcessor :: Conduit (MapRow Text) m (MapRow Text)
 -- >myProcessor = undefined
 -- >
--- >test = runResourceT $
--- >  sourceFile "test/BigFile.csv" $=
--- >  intoCSV defCSVSettings $=
--- >  myProcessor $=
--- >  (writeHeaders defCSVSettings >> fromCSV defCSVSettings) $$
+-- >test = runResourceT $ runConduit $
+-- >  sourceFile "test/BigFile.csv" .|
+-- >  intoCSV defCSVSettings .|
+-- >  myProcessor .|
+-- >  (writeHeaders defCSVSettings >> fromCSV defCSVSettings) .|
 -- >  sinkFile "test/BigFileOut.csv"
 class CSV s r where
 
@@ -126,13 +129,13 @@
   -----------------------------------------------------------------------------
   -- | Turn a stream of 's' into a stream of CSV row type. An example
   -- would be parsing a ByteString stream as rows of 'MapRow' 'Text'.
-  intoCSV :: (MonadThrow m) => CSVSettings -> Conduit s m r
+  intoCSV :: (MonadThrow m) => CSVSettings -> ConduitM s r m ()
 
   -----------------------------------------------------------------------------
   -- | Turn a stream of CSV row type back into a stream of 's'. An
   -- example would be rendering a stream of 'Row' 'ByteString' rows as
   -- 'Text'.
-  fromCSV :: Monad m => CSVSettings -> Conduit r m s
+  fromCSV :: Monad m => CSVSettings -> ConduitM r s m ()
 
 
 
@@ -145,8 +148,8 @@
     let
       sep = B.pack [c2w (csvSep s)]
       wrapField !f = case csvQuoteChar s of
-        Just !x -> (x `B8.cons` escape x f) `B8.snoc` x
-        _ -> f
+        Just !x-> (x `B8.cons` escape x f) `B8.snoc` x
+        _      -> f
       escape c str = B8.intercalate (B8.pack [c,c]) $ B8.split c str
     in B.intercalate sep . map wrapField $ r
 
@@ -161,8 +164,8 @@
     let
       sep = T.pack [csvSep s]
       wrapField !f = case csvQuoteChar s of
-        Just !x -> x `T.cons` escape x f `T.snoc` x
-        _ -> f
+        Just !x-> x `T.cons` escape x f `T.snoc` x
+        _      -> f
       escape c str = T.intercalate (T.pack [c,c]) $ T.split (== c) str
     in T.intercalate sep . map wrapField $ r
 
@@ -174,8 +177,8 @@
 -- | 'Row' instance using 'Text' based on 'ByteString' stream
 instance CSV ByteString (Row Text) where
     rowToStr s r = T.encodeUtf8 $ rowToStr s r
-    intoCSV set = intoCSV set =$= C.map (map T.decodeUtf8)
-    fromCSV set = fromCSV set =$= C.map T.encodeUtf8
+    intoCSV set = intoCSV set .| C.map (map T.decodeUtf8)
+    fromCSV set = fromCSV set .| C.map T.encodeUtf8
 
 
 
@@ -185,28 +188,28 @@
 -- lots of unnecessary overhead. Included for convenience.
 instance CSV ByteString (Row String) where
     rowToStr s r = rowToStr s $ map B8.pack r
-    intoCSV set = intoCSV set =$= C.map (map B8.unpack)
-    fromCSV set = C.map (map B8.pack) =$= fromCSV set
+    intoCSV set = intoCSV set .| C.map (map B8.unpack)
+    fromCSV set = C.map (map B8.pack) .| fromCSV set
 
 
 -- | Support for parsing rows in the 'Vector' form.
 instance (CSV s (Row s)) => CSV s (V.Vector s) where
     rowToStr s r = rowToStr s . V.toList $ r
-    intoCSV set = intoCSV set =$= C.map (V.fromList)
-    fromCSV set = C.map (V.toList) =$= fromCSV set
+    intoCSV set = intoCSV set .| C.map (V.fromList)
+    fromCSV set = C.map (V.toList) .| fromCSV set
 
 
 
 -------------------------------------------------------------------------------
 fromCSVRow :: (Monad m, IsString s, CSV s r)
-           => CSVSettings -> Conduit r m s
+           => CSVSettings -> ConduitM r s m ()
 fromCSVRow set = awaitForever $ \row -> mapM_ yield [rowToStr set row, "\n"]
 
 
 
 -------------------------------------------------------------------------------
-intoCSVRow :: (MonadThrow m, AttoparsecInput i) => Parser i (Maybe o) -> Conduit i m o
-intoCSVRow p = parse =$= puller
+intoCSVRow :: (MonadThrow m, AttoparsecInput i) => Parser i (Maybe o) -> ConduitM i o m ()
+intoCSVRow p = parse .| puller
   where
     parse = {-# SCC "conduitParser_p" #-} conduitParser p
     puller = {-# SCC "puller" #-}
@@ -224,8 +227,8 @@
 
 -------------------------------------------------------------------------------
 intoCSVMap :: (Ord a, MonadThrow m, CSV s [a])
-           => CSVSettings -> Conduit s m (MapRow a)
-intoCSVMap set = intoCSV set =$= (headers >>= converter)
+           => CSVSettings -> ConduitM s (MapRow a) m ()
+intoCSVMap set = intoCSV set .| (headers >>= converter)
   where
     headers = do
       mrow <- await
@@ -242,19 +245,19 @@
 instance (FromNamedRecord a, ToNamedRecord a, CSV s (MapRow ByteString)) =>
     CSV s (Named a) where
     rowToStr s a = rowToStr s . toNamedRecord . getNamed $ a
-    intoCSV set = intoCSV set =$= C.mapMaybe go
+    intoCSV set = intoCSV set .| C.mapMaybe go
         where
           go x = either (const Nothing) (Just . Named) $
                  runParser (parseNamedRecord x)
 
-    fromCSV set = C.map go =$= fromCSV set
+    fromCSV set = C.map go .| fromCSV set
         where
           go = toNamedRecord . getNamed
 
 
 -------------------------------------------------------------------------------
 fromCSVMap :: (Monad m, IsString s, CSV s [a])
-           => CSVSettings -> Conduit (M.Map k a) m s
+           => CSVSettings -> ConduitM (M.Map k a) s m ()
 fromCSVMap set = awaitForever push
   where
     push r = mapM_ yield [rowToStr set (M.elems r), "\n"]
@@ -267,11 +270,11 @@
 --
 -- Usage: Just chain this using the 'Monad' instance in your pipeline:
 --
--- > ... =$= writeHeaders settings >> fromCSV settings $$ sinkFile "..."
+-- > runConduit $ ... .| writeHeaders settings >> fromCSV settings .| sinkFile "..."
 writeHeaders
     :: (Monad m, CSV s (Row r), IsString s)
     => CSVSettings
-    -> Conduit (MapRow r) m s
+    -> ConduitM (MapRow r) s m ()
 writeHeaders set = do
   mrow <- await
   case mrow of
@@ -294,8 +297,9 @@
     => CSVSettings -- ^ Settings to use in deciphering stream
     -> FilePath    -- ^ Input file
     -> m (V.Vector a)
-readCSVFile set fp = liftIO . runResourceT $ sourceFile fp $= intoCSV set $$ hoist lift (sinkVector 10)
-
+readCSVFile set fp = liftIO . runResourceT $ runConduit $ sourceFile fp .| intoCSV set .| transPipe lift (sinkVector growthFactor)
+  where
+    growthFactor = 10
 
 
 -------------------------------------------------------------------------------
@@ -306,15 +310,27 @@
 -- For example for 'ByteString':
 --
 -- >>> s <- LB.readFile "my.csv"
--- >>> decodeCSV 'def' s :: Vector (Vector ByteString)
+-- >>> decodeCSV defCSVSettings s :: Either SomeException (Vector (Vector ByteString))
 --
--- will just work.
+-- will work as long as the data is comma separated.
 decodeCSV
-    :: (GV.Vector v a, CSV s a)
+    :: forall v a s. (GV.Vector v a, CSV s a)
     => CSVSettings
     -> s
     -> Either SomeException (v a)
-decodeCSV set bs = runST $ runExceptionT $ C.sourceList [bs] $= intoCSV set $$ hoist lift (sinkVector 10)
+decodeCSV set bs = runST $ runExceptT pipeline
+  where
+    src :: ConduitM () s (ExceptT SomeException (ST s1)) ()
+    src = C.sourceList [bs]
+    csvConvert :: ConduitM s a (ExceptT SomeException (ST s1)) ()
+    csvConvert = transPipe (ExceptT . runCatchT) csvConvert'
+    csvConvert' :: ConduitM s a (CatchT (ST s1)) ()
+    csvConvert' = intoCSV set
+    growthFactor = 10
+    sink :: ConduitM a Void (ExceptT SomeException (ST s1)) (v a)
+    sink = sinkVector growthFactor
+    pipeline :: ExceptT SomeException (ST s1) (v a)
+    pipeline = runConduit (src .| csvConvert .| sink)
 
 
 
@@ -332,8 +348,8 @@
   -> [a]
   -- ^ List of rows
   -> IO ()
-writeCSVFile set fo fmode rows = runResourceT $ do
-  C.sourceList rows $= fromCSV set $$
+writeCSVFile set fo fmode rows = runResourceT $ runConduit $ do
+  C.sourceList rows .| fromCSV set .|
     sinkIOHandle (openFile fo fmode)
 
 
@@ -344,16 +360,22 @@
 -- An easy way to run this function would be 'runResourceT' after
 -- feeding it all the arguments.
 mapCSVFile
-    :: (MonadResource m, MonadThrow m, CSV ByteString a, CSV ByteString b)
-    => CSVSettings
-    -- ^ Settings to use both for both input and output
-    -> (a -> [b])
-    -- ^ A mapping function
-    -> FilePath
-    -- ^ Input file
-    -> FilePath
-    -- ^ Output file
-    -> m ()
+    :: ( MonadResource m
+       , CSV ByteString a
+       , CSV ByteString b
+# if MIN_VERSION_resourcet(1,2,0)
+       , MonadThrow m
+#endif
+       )
+      => CSVSettings
+      -- ^ Settings to use both for both input and output
+      -> (a -> [b])
+      -- ^ A mapping function
+      -> FilePath
+      -- ^ Input file
+      -> FilePath
+      -- ^ Output file
+      -> m ()
 mapCSVFile set f fi fo =
   transformCSV set (sourceFile fi) (C.concatMap f) (sinkFile fo)
 
@@ -365,11 +387,11 @@
     :: (MonadThrow m, CSV s a, CSV s' b)
     => CSVSettings
     -- ^ Settings to be used for both input and output
-    -> Source m s
+    -> ConduitM () s m ()
     -- ^ A raw stream data source. Ex: 'sourceFile inFile'
-    -> Conduit a m b
+    -> ConduitM a b m ()
     -- ^ A transforming conduit
-    -> Sink s' m ()
+    -> ConduitM s' Void m ()
     -- ^ A raw stream data sink. Ex: 'sinkFile outFile'
     -> m ()
 transformCSV set = transformCSV' set set
@@ -393,18 +415,18 @@
     -- ^ Settings to be used for input
     -> CSVSettings
     -- ^ Settings to be used for output
-    -> Source m s
+    -> ConduitM () s m ()
     -- ^ A raw stream data source. Ex: 'sourceFile inFile'
-    -> Conduit a m b
+    -> ConduitM a b m ()
     -- ^ A transforming conduit
-    -> Sink s' m ()
+    -> ConduitM s' Void m ()
     -- ^ A raw stream data sink. Ex: 'sinkFile outFile'
     -> m ()
-transformCSV' setIn setOut source c sink =
-    source $=
-    intoCSV setIn $=
-    c $=
-    fromCSV setOut $$
+transformCSV' setIn setOut source c sink = runConduit $
+    source .|
+    intoCSV setIn .|
+    c .|
+    fromCSV setOut .|
     sink
 
 
@@ -433,8 +455,7 @@
             return $! v'
           Just x -> do
             v' <- case GMV.length v == i of
-                    True -> lift $ GMV.grow v by
+                    True  -> lift $ GMV.grow v by
                     False -> return v
             lift $ GMV.write v' i x
             go (i+1) v'
-
diff --git a/src/Data/CSV/Conduit/Conversion.hs b/src/Data/CSV/Conduit/Conversion.hs
--- a/src/Data/CSV/Conduit/Conversion.hs
+++ b/src/Data/CSV/Conduit/Conversion.hs
@@ -54,8 +54,7 @@
     , namedRecord
     ) where
 
-import Control.Applicative (Alternative, Applicative, (<*>), (<$>), (<|>),
-                                       empty, pure)
+import Control.Applicative as A
 import Control.Monad (MonadPlus, mplus, mzero)
 import Data.Attoparsec.ByteString.Char8 (double, parseOnly)
 import qualified Data.Attoparsec.ByteString.Char8 as A8
@@ -65,16 +64,16 @@
 
 import Data.Int (Int8, Int16, Int32, Int64)
 import qualified Data.Map as M
-import Data.Monoid (Monoid, mappend, mempty)
+import Data.Monoid as Monoid
 import qualified Data.Text as T
 import qualified Data.Text.Encoding as T
 import qualified Data.Text.Lazy as LT
 import qualified Data.Text.Lazy.Encoding as LT
-import Data.Traversable (traverse)
+import Data.Traversable as DT
 import Data.Vector (Vector, (!))
 import qualified Data.Vector as V
 import qualified Data.Vector.Unboxed as U
-import Data.Word (Word, Word8, Word16, Word32, Word64)
+import Data.Word as W
 import GHC.Float (double2Float)
 import Prelude hiding (lookup, takeWhile)
 
@@ -155,7 +154,7 @@
   
 #ifdef GENERICS
     default parseRecord :: (Generic a, GFromRecord (Rep a)) => Record -> Parser a
-    parseRecord r = to <$> gparseRecord r
+    parseRecord r = to A.<$> gparseRecord r
 #endif
 
 -- | Haskell lacks a single-element tuple type, so if you CSV data
@@ -309,7 +308,7 @@
             | otherwise     = show expected ++ "-tuple"
 
 instance FromField a => FromRecord [a] where
-    parseRecord = traverse parseField . V.toList
+    parseRecord = DT.traverse parseField . V.toList
 
 instance ToField a => ToRecord [a] where
     toRecord = V.fromList . map toField
@@ -553,7 +552,7 @@
     {-# INLINE toField #-}
 
 -- | Accepts an unsigned decimal number.
-instance FromField Word where
+instance FromField W.Word where
     parseField = parseUnsigned "Word"
     {-# INLINE parseField #-}
 
@@ -648,7 +647,7 @@
     toField = toField . T.pack
     {-# INLINE toField #-}
 
-parseSigned :: (Integral a, Num a) => String -> B.ByteString -> Parser a
+parseSigned :: (Integral a) => String -> B.ByteString -> Parser a
 parseSigned typ s = case parseOnly (A8.signed A8.decimal) s of
     Left err -> typeError typ s (Just err)
     Right n  -> pure n
@@ -779,7 +778,7 @@
                                    in unParser a kf' ks
     {-# INLINE mplus #-}
 
-instance Monoid (Parser a) where
+instance Monoid.Monoid (Parser a) where
     mempty  = fail "mempty"
     {-# INLINE mempty #-}
     mappend = mplus
diff --git a/src/Data/CSV/Conduit/Conversion/Internal.hs b/src/Data/CSV/Conduit/Conversion/Internal.hs
--- a/src/Data/CSV/Conduit/Conversion/Internal.hs
+++ b/src/Data/CSV/Conduit/Conversion/Internal.hs
@@ -24,9 +24,10 @@
 -- TODO: Add an optimized version for Integer.
 
 formatDecimal :: Integral a => a -> Builder
-{-# SPECIALIZE formatDecimal :: Int8 -> Builder #-}
 {-# RULES "formatDecimal/Int" formatDecimal = formatBoundedSigned
     :: Int -> Builder #-}
+{-# RULES "formatDecimal/Int8" formatDecimal = formatBoundedSigned
+    :: Int8 -> Builder #-}
 {-# RULES "formatDecimal/Int16" formatDecimal = formatBoundedSigned
     :: Int16 -> Builder #-}
 {-# RULES "formatDecimal/Int32" formatDecimal = formatBoundedSigned
@@ -43,6 +44,7 @@
     :: Word32 -> Builder #-}
 {-# RULES "formatDecimal/Word64" formatDecimal = formatPositive
     :: Word64 -> Builder #-}
+{-# NOINLINE formatDecimal #-}
 formatDecimal i
     | i < 0     = minus <>
                   if i <= -128
diff --git a/test/Bench.hs b/test/Bench.hs
deleted file mode 100644
--- a/test/Bench.hs
+++ /dev/null
@@ -1,21 +0,0 @@
-
-module Main where
-
-import qualified Data.ByteString.Char8 as B
-import Data.Map ((!))
-import Data.Text
-import System.Directory
-import System.Environment
-import Data.CSV.Conduit
-
-
-main = do
-    inPath:_ <- getArgs
-    runResourceT $ mapCSVFile defCSVSettings idF inPath outPath
-    removeFile outPath
-  where
-    outPath = "test/testOut.csv"
-
-
-idF :: Row Text -> [Row Text]
-idF = return . id
diff --git a/test/Test.hs b/test/Test.hs
--- a/test/Test.hs
+++ b/test/Test.hs
@@ -1,18 +1,22 @@
-{-# LANGUAGE OverloadedStrings   #-}
-{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings     #-}
+{-# LANGUAGE ScopedTypeVariables   #-}
 
 module Main where
 
+import           Control.Exception
 import qualified Data.ByteString.Char8          as B
 import           Data.Map                       ((!))
+import           Data.Monoid
 import           Data.Text
 import qualified Data.Vector                    as V
 import           System.Directory
 import           Test.Framework                 (Test, defaultMain, testGroup)
 import           Test.Framework.Providers.HUnit
-import           Test.HUnit                     ((@=?))
+import           Test.HUnit                     (assertFailure, (@=?))
 
 import           Data.CSV.Conduit
+import           Data.CSV.Conduit.Conversion
 
 
 main :: IO ()
@@ -20,7 +24,10 @@
 
 
 tests :: [Test]
-tests = [testGroup "Basic Ops" baseTests]
+tests =
+  [ testGroup "Basic Ops" baseTests
+  , testGroup "decodeCSV" decodeCSVTests
+  ]
 
 
 baseTests :: [Test]
@@ -28,6 +35,36 @@
   [ testCase "mapping with id works" test_identityMap
   , testCase "simple parsing works" test_simpleParse
   ]
+
+
+decodeCSVTests :: [Test]
+decodeCSVTests =
+  [ testCase "parses a CSV" $ do
+      let efoos = decodeCSV defCSVSettings ("Foo\nfoo" :: B.ByteString)
+      case efoos :: Either SomeException (V.Vector (Named Foo)) of
+        Left e     -> assertFailure (show e)
+        Right foos -> V.fromList [Named Foo] @=? foos
+  , testCase "eats parse errors, evidently" $ do
+      let efoos = decodeCSV defCSVSettings ("Foo\nbad" :: B.ByteString)
+      case efoos :: Either SomeException (V.Vector (Named Foo)) of
+        Left e     -> assertFailure (show e)
+        Right foos -> mempty @=? foos
+  ]
+
+
+data Foo = Foo deriving (Show, Eq)
+
+
+instance FromNamedRecord Foo where
+  parseNamedRecord nr = do
+    s <- nr .: "Foo"
+    case s of
+      "foo" -> pure Foo
+      _ -> fail ("Expected \"foo\" but got " <> B.unpack s)
+
+
+instance ToNamedRecord Foo where
+  toNamedRecord Foo = namedRecord ["Foo" .= ("foo" :: B.ByteString)]
 
 
 test_identityMap :: IO ()
