diff --git a/Codec/Binary/Base91.hs b/Codec/Binary/Base91.hs
--- a/Codec/Binary/Base91.hs
+++ b/Codec/Binary/Base91.hs
@@ -1,22 +1,45 @@
 -- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.
 -- Informed by Mario Rodriguez's C++ implementation.
 
+{-# LANGUAGE ConstraintKinds #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeFamilies #-}
 
 module Codec.Binary.Base91 (alphabet, decode, encode) where
 
-import Codec.Binary.Base91.Control (Applicative' (..), Foldable' (..))
 import Data.Bits ((.&.), (.|.), shiftL, shiftR)
 import Data.Char (ord)
-import Data.Monoid (mappend, mconcat, mempty)
+import Data.Monoid (Monoid, mappend, mconcat, mempty)
+import Data.MonoTraversable (Element, MonoFoldable, MonoPointed, ofoldl', opoint)
 import Data.Word (Word8)
 
+type Input i e = (MonoFoldable i, Element i ~ e)
+type Output o e = (MonoPointed o, Element o ~ e, Monoid o)
 
--- | Generically encodes a 'Word8' sequence to a 'Char' sequence in Base91 form.
-encode :: forall i o. (Foldable' i, Element i ~ Word8, Applicative' o, Item o ~ Char) => i -> o
-encode input = g . fold' f (0, 0, mempty) $ input where
+{-
+encodeToString :: Input i Word8 => i -> [Char]
+encodeToString = encode
 
+decodeToBytes :: Input i Char => i -> [Word8]
+decodeToBytes = decode
+
+encodeBytes :: Output o Char => [Word8] -> o
+encodeBytes = encode
+
+decodeString :: Output o Word8 => [Char] -> o
+decodeString = decode
+
+encodeBytesToString :: [Word8] -> [Char]
+encodeBytesToString = encode
+
+decodeStringToBytes :: [Char] -> [Word8]
+decodeStringToBytes = decode
+-}
+
+-- | Encodes a 'Word8' input sequence to a 'Char' output sequence in Base91 form; the opposite of 'decode'.
+encode :: forall i o. (Input i Word8, Output o Char) => i -> o
+encode input = g . ofoldl' f (0, 0, mempty) $ input where
+
   f :: (Int, Int, o) -> Word8 -> (Int, Int, o)
   f (queue, nbits, output) w =
     let queue' = queue .|. (fromWord8 w `shiftL` nbits)
@@ -27,20 +50,20 @@
           (v, q, n)   = if value > 88
             then (value,  queue' `shiftR` 13, nbits' - 13)
             else (value', queue' `shiftR` 14, nbits' - 14)
-          x = pure' $ alphabet !! (v `mod` 91)
-          y = pure' $ alphabet !! (v `div` 91)
+          x = opoint $ alphabet !! (v `mod` 91)
+          y = opoint $ alphabet !! (v `div` 91)
       in (q, n, mconcat [output, x, y])
 
   g :: (Int, Int, o) -> o
   g (_,     0,     output) = output
   g (queue, nbits, output) = mconcat [output, x, y]
-    where x                           = pure' $ alphabet !! (queue `mod` 91)
-          y | nbits > 7 || queue > 90 = pure' $ alphabet !! (queue `div` 91)
+    where x                           = opoint $ alphabet !! (queue `mod` 91)
+          y | nbits > 7 || queue > 90 = opoint $ alphabet !! (queue `div` 91)
             | otherwise               = mempty
 
--- | Generically decodes a 'Word8' sequence from a 'Char' sequence in Base91 form.
-decode :: forall i o. (Foldable' i, Element i ~ Char, Applicative' o, Item o ~ Word8) => i -> o
-decode input = g . fold' f (0, 0, -1, mempty) $ input where
+-- | Decodes a 'Word8' output sequence from a 'Char' input sequence in Base91 form; the opposite of 'encode'.
+decode :: forall i o. (Input i Char, Output o Word8) => i -> o
+decode input = g . ofoldl' f (0, 0, -1, mempty) $ input where
 
   f :: (Int, Int, Int, o) -> Char -> (Int, Int, Int, o)
   f (queue, nbits, value, output) c =
@@ -51,14 +74,14 @@
                 q = queue .|. (v `shiftL` nbits)
                 n = nbits + (if (v .&. 8191) > 88 then 13 else 14)
                 (queue', nbits', x, y) = if n - 8 > 7
-                  then (q `shiftR` 16, n - 16, pure' $ toWord8 q, pure' $ toWord8 $ q `shiftR` 8)
-                  else (q `shiftR` 8,  n - 8,  pure' $ toWord8 q, mempty)
+                  then (q `shiftR` 16, n - 16, opoint $ toWord8 q, opoint $ toWord8 $ q `shiftR` 8)
+                  else (q `shiftR` 8,  n - 8,  opoint $ toWord8 q, mempty)
              in (queue', nbits', -1, mconcat [output, x, y])
 
   g :: (Int, Int, Int, o) -> o
   g (_,     _,     -1,  output) = output
   g (queue, nbits, value, output) = mappend output x
-    where x = pure' $ toWord8 $ queue .|. (value `shiftL` nbits)
+    where x = opoint $ toWord8 $ queue .|. (value `shiftL` nbits)
 
 toWord8 :: Int -> Word8
 toWord8 = fromIntegral
diff --git a/Codec/Binary/Base91/ByteString.hs b/Codec/Binary/Base91/ByteString.hs
deleted file mode 100644
--- a/Codec/Binary/Base91/ByteString.hs
+++ /dev/null
@@ -1,29 +0,0 @@
--- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.
-
-{-# LANGUAGE TypeFamilies #-}
-
-module Codec.Binary.Base91.ByteString (decode, encode) where
-
-import Codec.Binary.Base91.Control (Applicative' (..), Foldable' (..))
-import Data.ByteString (ByteString)
-import Data.Word (Word8)
-import qualified Codec.Binary.Base91 as Base91
-import qualified Data.ByteString     as BS
-
-
--- | Encodes a 'ByteString' to ['Char'] in Base91; the opposite of 'decode'.
-encode ::ByteString -> [Char]
-encode = Base91.encode
-
--- | Decodes a 'ByteString' from ['Char'] in Base91; the opposite of 'encode'.
-decode :: [Char] -> ByteString
-decode = Base91.decode
-
-
-instance Applicative' ByteString where
-    type Item ByteString = Word8
-    pure' = BS.singleton
-
-instance Foldable' ByteString where
-    type Element ByteString = Word8
-    fold' = BS.foldl'
diff --git a/Codec/Binary/Base91/ByteString/Lazy.hs b/Codec/Binary/Base91/ByteString/Lazy.hs
deleted file mode 100644
--- a/Codec/Binary/Base91/ByteString/Lazy.hs
+++ /dev/null
@@ -1,29 +0,0 @@
--- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.
-
-{-# LANGUAGE TypeFamilies #-}
-
-module Codec.Binary.Base91.ByteString.Lazy (decode, encode) where
-
-import Codec.Binary.Base91.Control (Applicative' (..), Foldable' (..))
-import Data.ByteString.Lazy (ByteString)
-import Data.Word (Word8)
-import qualified Codec.Binary.Base91  as Base91
-import qualified Data.ByteString.Lazy as BSL
-
-
--- | Encodes a (lazy) 'ByteString' to ['Char'] in Base91; the opposite of 'decode'.
-encode ::ByteString -> [Char]
-encode = Base91.encode
-
--- | Decodes a (lazy) 'ByteString' from ['Char'] in Base91; the opposite of 'encode'.
-decode :: [Char] -> ByteString
-decode = Base91.decode
-
-
-instance Applicative' ByteString where
-    type Item ByteString = Word8
-    pure' = BSL.singleton
-
-instance Foldable' ByteString where
-    type Element ByteString = Word8
-    fold' = BSL.foldl'
diff --git a/Codec/Binary/Base91/Control.hs b/Codec/Binary/Base91/Control.hs
deleted file mode 100644
--- a/Codec/Binary/Base91/Control.hs
+++ /dev/null
@@ -1,29 +0,0 @@
--- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.
-
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE UndecidableInstances #-}
-
-module Codec.Binary.Base91.Control (Applicative' (..), Foldable' (..)) where
-
-import Control.Applicative (Applicative, pure)
-import Data.Foldable (Foldable, foldl')
-import Data.Monoid (Monoid)
-
--- A version of 'Applicative' compatible with monomorphic containers.
-class (Monoid a) => Applicative' a where
-    type Item a :: *
-    pure' :: Item a -> a
-
-instance (Applicative a, Monoid (a i)) => Applicative' (a i) where
-  type Item (a i) = i
-  pure' = pure
-
--- A version of 'Foldable' compatible with monomorphic containers.
-class Foldable' f where
-    type Element f :: *
-    fold' :: (x -> Element f -> x) -> x -> f -> x
-
-instance (Foldable f) => Foldable' (f e) where
-  type Element (f e) = e
-  fold' = foldl'
diff --git a/Codec/Binary/Base91/Efficient.hs b/Codec/Binary/Base91/Efficient.hs
deleted file mode 100644
--- a/Codec/Binary/Base91/Efficient.hs
+++ /dev/null
@@ -1,18 +0,0 @@
--- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.
-
-module Codec.Binary.Base91.Efficient (decode, encode) where
-
-import Codec.Binary.Base91.ByteString hiding (decode, encode)
-import Codec.Binary.Base91.Text       hiding (decode, encode)
-import Data.ByteString (ByteString)
-import Data.Text (Text)
-import qualified Codec.Binary.Base91 as Base91
-
-
--- | Encodes 'ByteString' to 'Text' in Base91; the opposite of 'decode'.
-encode :: ByteString -> Text
-encode = Base91.encode
-
--- | Decodes 'ByteString' from 'Text' in Base91; the opposite of 'encode'.
-decode :: Text -> ByteString
-decode = Base91.decode
diff --git a/Codec/Binary/Base91/Efficient/Lazy.hs b/Codec/Binary/Base91/Efficient/Lazy.hs
deleted file mode 100644
--- a/Codec/Binary/Base91/Efficient/Lazy.hs
+++ /dev/null
@@ -1,18 +0,0 @@
--- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.
-
-module Codec.Binary.Base91.Efficient.Lazy (decode, encode) where
-
-import Codec.Binary.Base91.ByteString.Lazy hiding (decode, encode)
-import Codec.Binary.Base91.Text.Lazy       hiding (decode, encode)
-import Data.ByteString.Lazy (ByteString)
-import Data.Text.Lazy (Text)
-import qualified Codec.Binary.Base91 as Base91
-
-
--- | Encodes 'ByteString' to 'Text' in Base91; the opposite of 'decode'.
-encode :: ByteString -> Text
-encode = Base91.encode
-
--- | Decodes 'ByteString' from 'Text' in Base91; the opposite of 'encode'.
-decode :: Text -> ByteString
-decode = Base91.decode
diff --git a/Codec/Binary/Base91/String.hs b/Codec/Binary/Base91/String.hs
deleted file mode 100644
--- a/Codec/Binary/Base91/String.hs
+++ /dev/null
@@ -1,15 +0,0 @@
--- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.
-
-module Codec.Binary.Base91.String (decode, encode) where
-
-import Data.Word (Word8)
-import qualified Codec.Binary.Base91 as Base91
-
-
--- | Encodes ['Word8'] to a 'String' in Base91; the opposite of 'decode'.
-encode :: [Word8] -> String
-encode = Base91.encode
-
--- | Decodes ['Word8'] from a 'String' in Base91; the opposite of 'encode'.
-decode :: String -> [Word8]
-decode = Base91.decode
diff --git a/Codec/Binary/Base91/Text.hs b/Codec/Binary/Base91/Text.hs
deleted file mode 100644
--- a/Codec/Binary/Base91/Text.hs
+++ /dev/null
@@ -1,29 +0,0 @@
--- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.
-
-{-# LANGUAGE TypeFamilies #-}
-
-module Codec.Binary.Base91.Text (decode, encode) where
-
-import Codec.Binary.Base91.Control (Applicative' (..), Foldable' (..))
-import Data.Text (Text)
-import Data.Word (Word8)
-import qualified Codec.Binary.Base91 as Base91
-import qualified Data.Text           as T
-
-
--- | Encodes ['Word8'] to 'Text' in Base91; the opposite of 'decode'.
-encode :: [Word8] -> Text
-encode = Base91.encode
-
--- | Decodes ['Word8'] from 'Text' in Base91; the opposite of 'encode'.
-decode :: Text -> [Word8]
-decode = Base91.decode
-
-
-instance Applicative' Text where
-    type Item (Text) = Char
-    pure' = T.singleton
-
-instance Foldable' Text where
-    type Element (Text) = Char
-    fold' = T.foldl'
diff --git a/Codec/Binary/Base91/Text/Lazy.hs b/Codec/Binary/Base91/Text/Lazy.hs
deleted file mode 100644
--- a/Codec/Binary/Base91/Text/Lazy.hs
+++ /dev/null
@@ -1,29 +0,0 @@
--- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.
-
-{-# LANGUAGE TypeFamilies #-}
-
-module Codec.Binary.Base91.Text.Lazy (decode, encode) where
-
-import Codec.Binary.Base91.Control (Applicative' (..), Foldable' (..))
-import Data.Text.Lazy (Text)
-import Data.Word (Word8)
-import qualified Codec.Binary.Base91 as Base91
-import qualified Data.Text.Lazy      as TL
-
-
--- | Encodes ['Word8'] to (lazy) 'Text' in Base91; the opposite of 'decode'.
-encode :: [Word8] -> Text
-encode = Base91.encode
-
--- | Decodes ['Word8'] from (lazy) 'Text' in Base91; the opposite of 'encode'.
-decode :: Text -> [Word8]
-decode = Base91.decode
-
-
-instance Applicative' Text where
-    type Item (Text) = Char
-    pure' = TL.singleton
-
-instance Foldable' Text where
-    type Element (Text) = Char
-    fold' = TL.foldl'
diff --git a/Main.hs b/Main.hs
--- a/Main.hs
+++ b/Main.hs
@@ -2,11 +2,12 @@
 
 module Main (main) where
 
-import Codec.Binary.Base91.Efficient as Base91
-import Data.ByteString as BS
-import Data.Text.IO as T
 import System.Environment (getArgs, getProgName)
 
+import qualified Codec.Binary.Base91 as Base91
+import qualified Data.ByteString     as BS
+import qualified Data.Text.IO        as T
+
 main :: IO ()
 main = getProgName >>= \name -> getArgs >>= \args -> case name:args of
     "b91enc":[]    -> encode
@@ -18,5 +19,5 @@
     _              -> error "missing or invalid arguments"
 
   where
-    encode  = BS.getContents >>= T.putStrLn . Base91.encode
-    decode  = T.getContents >>= BS.putStr . Base91.decode
+    encode = BS.getContents >>= T.putStrLn . Base91.encode
+    decode = T.getContents >>= BS.putStr . Base91.decode
diff --git a/Test.hs b/Test.hs
--- a/Test.hs
+++ b/Test.hs
@@ -1,17 +1,14 @@
 -- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.
 
-import qualified Codec.Binary.Base91.ByteString      as BS'  (decode, encode)
-import qualified Codec.Binary.Base91.ByteString.Lazy as BSL' (decode, encode)
-import qualified Codec.Binary.Base91.Efficient       as E'   (decode, encode)
-import qualified Codec.Binary.Base91.Efficient.Lazy  as EL'  (decode, encode)
-import qualified Codec.Binary.Base91.String          as S'   (decode, encode)
-import qualified Codec.Binary.Base91.Text            as T'   (decode, encode)
-import qualified Codec.Binary.Base91.Text.Lazy       as TL'  (decode, encode)
+{-# LANGUAGE TypeFamilies #-}
+
+import Codec.Binary.Base91 (decode, encode)
+import Data.Word (Word8)
+import Test.QuickCheck (quickCheck)
 import qualified Data.ByteString      as BS
 import qualified Data.ByteString.Lazy as BSL
 import qualified Data.Text            as T
 import qualified Data.Text.Lazy       as TL
-import Test.QuickCheck
 
 main :: IO ()
 main = do
@@ -20,8 +17,8 @@
     testByteStringLazy
     testText
     testTextLazy
-    testEfficient
-    testEfficientLazy
+    testByteString_Text
+    testByteStringLazy_TextLazy
   where
 
   -- Note that the reverse identities, e.g. encode (decode cs) == cs, aren't true because not every
@@ -30,58 +27,67 @@
 
   testString = do
       quickCheck $ prop_identity
-      quickCheck $ example ([], [])
+      quickCheck $ example empty
       quickCheck $ example helloWorld
     where
-      prop_identity ws = S'.decode (S'.encode ws) == ws
-      example (ws, cs) = S'.encode ws == cs && S'.decode cs == ws
+      prop_identity :: [Word8] -> Bool
+      prop_identity ws = decode (encode ws :: [Char]) == ws
+      example (ws, cs) = (encode ws :: [Char]) == cs && decode cs == ws
 
   testByteString = do
       quickCheck $ prop_identity
-      quickCheck $ example ([], [])
+      quickCheck $ example empty
       quickCheck $ example helloWorld
     where
-      prop_identity ws = BS'.decode (BS'.encode bs) == bs           where bs = BS.pack ws
-      example (ws, cs) = BS'.encode bs == cs && BS'.decode cs == bs where bs = BS.pack ws
+      prop_identity :: [Word8] -> Bool
+      prop_identity ws = decode (encode bs :: [Char]) == bs             where bs = BS.pack ws
+      example (ws, cs) = (encode bs :: [Char]) == cs && decode cs == bs where bs = BS.pack ws
 
   testByteStringLazy = do
       quickCheck $ prop_identity
-      quickCheck $ example ([], [])
+      quickCheck $ example empty
       quickCheck $ example helloWorld
     where
-      prop_identity ws = BSL'.decode (BSL'.encode bs) == bs           where bs = BSL.pack ws
-      example (ws, cs) = BSL'.encode bs == cs && BSL'.decode cs == bs where bs = BSL.pack ws
+      prop_identity :: [Word8] -> Bool
+      prop_identity ws = decode (encode bs :: [Char]) == bs             where bs = BSL.pack ws
+      example (ws, cs) = (encode bs :: [Char]) == cs && decode cs == bs where bs = BSL.pack ws
 
   testText = do
       quickCheck $ prop_identity
-      quickCheck $ example ([], [])
+      quickCheck $ example empty
       quickCheck $ example helloWorld
     where
-      prop_identity ws = T'.decode (T'.encode ws) == ws
-      example (ws, cs) = T'.encode ws == t && T'.decode t == ws where t = T.pack cs
+      prop_identity :: [Word8] -> Bool
+      prop_identity ws = decode (encode ws :: T.Text) == ws
+      example (ws, cs) = (encode ws :: T.Text) == t && decode t == ws where t = T.pack cs
 
   testTextLazy = do
       quickCheck $ prop_identity
-      quickCheck $ example ([], [])
+      quickCheck $ example empty
       quickCheck $ example helloWorld
     where
-      prop_identity ws = TL'.decode (TL'.encode ws) == ws
-      example (ws, cs) = TL'.encode ws == t && TL'.decode t == ws where t = TL.pack cs
+      prop_identity :: [Word8] -> Bool
+      prop_identity ws = decode (encode ws :: TL.Text) == ws
+      example (ws, cs) = (encode ws :: TL.Text) == t && decode t == ws where t = TL.pack cs
 
-  testEfficient = do
+  testByteString_Text = do
       quickCheck $ prop_identity
-      quickCheck $ example ([], [])
+      quickCheck $ example empty
       quickCheck $ example helloWorld
     where
-      prop_identity ws = E'.decode (E'.encode bs) == bs          where bs = BS.pack ws
-      example (ws, cs) = E'.encode bs == t && E'.decode t  == bs where (bs, t) = (BS.pack ws, T.pack cs)
+      prop_identity :: [Word8] -> Bool
+      prop_identity ws = decode (encode bs :: T.Text) == bs            where bs = BS.pack ws
+      example (ws, cs) = (encode bs :: T.Text) == t && decode t  == bs where (bs, t) = (BS.pack ws, T.pack cs)
 
-  testEfficientLazy = do
+  testByteStringLazy_TextLazy = do
       quickCheck $ prop_identity
-      quickCheck $ example ([], [])
+      quickCheck $ example empty
       quickCheck $ example helloWorld
     where
-      prop_identity ws = EL'.decode (EL'.encode bs) == bs          where bs = BSL.pack ws
-      example (ws, cs) = EL'.encode bs == t && EL'.decode t  == bs where (bs, t) = (BSL.pack ws, TL.pack cs)
+      prop_identity :: [Word8] -> Bool
+      prop_identity ws = decode (encode bs :: TL.Text) == bs            where bs = BSL.pack ws
+      example (ws, cs) = (encode bs :: TL.Text) == t && decode t  == bs where (bs, t) = (BSL.pack ws, TL.pack cs)
 
+  empty, helloWorld :: ([Word8], [Char])
+  empty      = ([], "")
   helloWorld = ([72,101,108,108,111,44,32,119,111,114,108,100,33,10], ">OwJh>}A\"=r@@Y?FF") -- "Hello, World!\n"
diff --git a/base91.cabal b/base91.cabal
--- a/base91.cabal
+++ b/base91.cabal
@@ -1,51 +1,30 @@
 Name:                  base91
-Version:               1.1.0
+Version:               2.0.0
 Author:                Alvaro J. Genial
 Maintainer:            ajg
 Homepage:              https://github.com/ajg/base91
 Synopsis:              A Base91 Encoder & Decoder
 Description:           An implementation of Base91 encoding & decoding of arbitrary bytes (octets)
-                       to/from characters (all in the ASCII printable range); it includes support
-                       for plain Strings, as well as optional support for ByteString and/or Text and
-                       their lazy variants; see the Flags section for details.
+                       to/from characters (all in the ASCII printable range)
 License:               MIT
 License-File:          LICENSE.md
 Category:              Codec
 Build-Type:            Simple
 Cabal-Version:         >= 1.8
 
-Flag ByteString
-  Description:         Enable support for Data.ByteString and Data.ByteString.Lazy.
-  Default:             True
-
-Flag Text
-  Description:         Enable support for Data.Text and Data.Text.Lazy.
-  Default:             True
-
 Library
-  Build-Depends:       base >= 4 && < 5
-  Exposed-Modules:     Codec.Binary.Base91, Codec.Binary.Base91.Control, Codec.Binary.Base91.String
-
-  if flag(ByteString)
-    Build-Depends:     bytestring
-    Exposed-Modules:   Codec.Binary.Base91.ByteString, Codec.Binary.Base91.ByteString.Lazy
-
-  if flag(Text)
-    Build-Depends:     text
-    Exposed-Modules:   Codec.Binary.Base91.Text, Codec.Binary.Base91.Text.Lazy
-
-  if flag(ByteString) && flag(Text)
-    Exposed-Modules:   Codec.Binary.Base91.Efficient, Codec.Binary.Base91.Efficient.Lazy
+  Build-Depends:       base >= 4 && < 5, mono-traversable
+  Exposed-Modules:     Codec.Binary.Base91
 
 Executable base91
   Main-is:             Main.hs
-  Build-Depends:       base, base91, bytestring, text
+  Build-Depends:       base, base91, bytestring, mono-traversable, text
 
 Test-Suite tests
   Hs-Source-Dirs:      .
   Main-Is:             Test.hs
   Type:                exitcode-stdio-1.0
-  Build-Depends:       base, base91, bytestring, text, QuickCheck
+  Build-Depends:       base, base91, bytestring, mono-traversable, text, QuickCheck
 
 Source-Repository head
   type:                git
