diff --git a/ClassyPrelude.hs b/ClassyPrelude.hs
--- a/ClassyPrelude.hs
+++ b/ClassyPrelude.hs
@@ -8,17 +8,21 @@
       module CorePrelude
       -- * Standard
       -- ** Monoid
-    , concat
     , empty
     , append
     , (++)
       -- ** Monad
     , module Control.Monad
+      -- ** Mutable references
+    , module Control.Concurrent.MVar.Lifted
+    , module Data.IORef.Lifted
       -- * Non-standard
       -- ** List-like classes
     , map
+    , concat
     , concatMap
     , filter
+    , find
     , length
     , singleton
     , null
@@ -53,8 +57,15 @@
     , reverse
     , readMay
     , replicate
+    , intercalate
+    , intersperse
     , encodeUtf8
     , decodeUtf8
+    , subsequences
+    , permutations
+    , partition
+    , nub
+    , nubBy
       -- ** Map-like
     , lookup
     , insert
@@ -64,9 +75,14 @@
     , elem
       -- ** Text-like
     , show
-      -- ** Files
+    , toLower
+    , toUpper
+    , toCaseFold
+      -- ** IO
     , readFile
     , writeFile
+    , getLine
+    , print
       -- ** Chunking
     , toChunks
     , fromChunks
@@ -85,9 +101,11 @@
 
 import qualified Prelude
 import qualified Data.Maybe
-import Control.Monad (when, unless, void, liftM, ap, forever)
+import Control.Monad (when, unless, void, liftM, ap, forever, join, sequence, sequence_)
+import Control.Concurrent.MVar.Lifted
+import Data.IORef.Lifted
 
-import CorePrelude
+import CorePrelude hiding (print)
 import ClassyPrelude.Classes
 
 import ClassyPrelude.ByteString ()
@@ -129,10 +147,6 @@
 repack :: (CanPack a i, CanPack b i) => a -> b
 repack = pack . unpack
 
-concat :: Monoid m => [m] -> m
-concat = mconcat
-{-# INLINE concat #-}
-
 append :: Monoid m => m -> m -> m
 append = mappend
 {-# INLINE append #-}
@@ -146,6 +160,9 @@
 (++) = mappend
 {-# INLINE (++) #-}
 
+intercalate :: (CanConcat c i, CanIntersperse c i) => i -> c -> i
+intercalate xs xss = concat (intersperse xs xss)
+
 asByteString :: ByteString -> ByteString
 asByteString = id
 
@@ -184,3 +201,6 @@
 
 elem :: CanMember c k => k -> c -> Bool
 elem = member
+
+print :: (Show a, MonadIO m) => a -> m ()
+print = liftIO . Prelude.print
diff --git a/ClassyPrelude/ByteString.hs b/ClassyPrelude/ByteString.hs
--- a/ClassyPrelude/ByteString.hs
+++ b/ClassyPrelude/ByteString.hs
@@ -30,6 +30,8 @@
 instance CanPack ByteString Word8 where
     pack = S.pack
     unpack = S.unpack
+instance CanIntersperse ByteString Word8 where
+    intersperse = S.intersperse
 instance MonadIO m => CanReadFile (m ByteString) where
     readFile = liftIO . S.readFile . F.encodeString
 instance CanWriteFileFunc ByteString where
@@ -59,3 +61,9 @@
         | x `S.isSuffixOf` y = Prelude.Just (S.take (S.length y Prelude.- S.length x) y)
         | Prelude.otherwise = Prelude.Nothing
     isSuffixOf = S.isSuffixOf
+
+instance MonadIO m => CanGetLine (m ByteString) where
+    getLine = liftIO S.getLine
+
+instance CanPartition ByteString Word8 where
+    partition = S.partition
diff --git a/ClassyPrelude/Classes.hs b/ClassyPrelude/Classes.hs
--- a/ClassyPrelude/Classes.hs
+++ b/ClassyPrelude/Classes.hs
@@ -6,7 +6,8 @@
 module ClassyPrelude.Classes where
 
 import qualified Prelude
-import Prelude (Monad)
+import Prelude (Monad, (.), ($))
+import qualified Data.List
 import qualified Filesystem.Path.CurrentOS as F
 import Control.Monad.IO.Class (MonadIO)
 
@@ -16,7 +17,6 @@
     mapFunc :: (i -> o) -> ci -> co
 instance CanMapFunc ci co i o => CanMap (ci -> co) i o where
     map = mapFunc
-
 class CanConcatMap f i o where
     concatMap :: (i -> o) -> f
 class CanConcatMapFunc ci co i o | ci -> i, co -> o, ci o -> co, co i -> ci where
@@ -50,7 +50,14 @@
 class CanPack c i | c -> i where
     pack :: [i] -> c
     unpack :: c -> [i]
+    subsequences :: c -> [c]
+    subsequences = Data.List.map pack . Data.List.subsequences . unpack
+    permutations :: c -> [c]
+    permutations = Data.List.map pack . Data.List.permutations . unpack
 
+class CanIntersperse c i | c -> i where
+    intersperse :: i -> c -> c
+
 class Monad m => CanMapM f m i o where
     mapM :: (i -> m o) -> f
 class Monad m => CanMapMFunc ci mco m i o | ci -> i, mco -> m o, ci o m -> mco, mco i -> ci where
@@ -179,3 +186,34 @@
     decodeUtf8Func :: ci -> co
 instance CanDecodeUtf8Func ci co => CanDecodeUtf8 (ci -> co) where
     decodeUtf8 = decodeUtf8Func
+
+class CanToStrict a b where
+    toStrict :: a -> b
+    fromStrict :: b -> a
+
+class CanGetLine a where
+    getLine :: a
+
+class CanToLower a where
+    toLower :: a -> a
+
+class CanToUpper a where
+    toUpper :: a -> a
+
+class CanToCaseFold a where
+    toCaseFold :: a -> a
+
+class CanFind c i | c -> i where
+    find :: (i -> Prelude.Bool) -> c -> Prelude.Maybe i
+
+class CanConcat c i | c -> i where
+    concat :: c -> i
+
+class CanPartition c i | c -> i where
+    partition :: (i -> Prelude.Bool) -> c -> (c, c)
+
+class CanNubBy c i | c -> i where
+    nubBy :: (i -> i -> Prelude.Bool) -> c -> c
+
+    nub :: (Prelude.Ord i, CanNubBy c i) => c -> c
+    nub = nubBy (Prelude.==)
diff --git a/ClassyPrelude/FilePath.hs b/ClassyPrelude/FilePath.hs
--- a/ClassyPrelude/FilePath.hs
+++ b/ClassyPrelude/FilePath.hs
@@ -7,11 +7,14 @@
 import qualified Prelude
 import Prelude ((.), Char)
 import ClassyPrelude.Classes
+import qualified Data.List
 import qualified Filesystem.Path.CurrentOS as F
 
 instance CanPack F.FilePath Prelude.Char where
     pack = F.decodeString
     unpack = F.encodeString
+instance CanIntersperse F.FilePath Prelude.Char where
+    intersperse c = pack . Data.List.intersperse c . unpack
 instance CanStripPrefix F.FilePath where
     stripPrefix = F.stripPrefix
     isPrefixOf a b =
diff --git a/ClassyPrelude/HashMap.hs b/ClassyPrelude/HashMap.hs
--- a/ClassyPrelude/HashMap.hs
+++ b/ClassyPrelude/HashMap.hs
@@ -13,6 +13,11 @@
 import qualified Data.HashMap.Strict as Map
 import Data.Hashable (Hashable)
 
+import Data.Monoid (Monoid)
+import qualified Data.Monoid as Monoid
+import Data.Foldable (Foldable)
+import qualified Data.Foldable as Foldable
+
 type Map = HashMap
 
 instance CanMapFunc (Map k v1) (Map k v2) v1 v2 where
@@ -34,3 +39,9 @@
     insertVal = Map.insert
 instance (Prelude.Eq k, Hashable k) => CanDeleteVal (Map k v) k where
     deleteVal = Map.delete
+instance CanFind (Map k v) v where
+    find = Foldable.find
+instance (Monoid v) => CanConcat (Map k v) v where
+    concat = Foldable.fold
+instance Hashable k => CanPartition (Map k v) v where
+    partition p m = (Map.filter p m, Map.filter (Prelude.not . p) m)
diff --git a/ClassyPrelude/LByteString.hs b/ClassyPrelude/LByteString.hs
--- a/ClassyPrelude/LByteString.hs
+++ b/ClassyPrelude/LByteString.hs
@@ -33,6 +33,8 @@
 instance CanPack LByteString Word8 where
     pack = L.pack
     unpack = L.unpack
+instance CanIntersperse LByteString Word8 where
+    intersperse = L.intersperse
 instance MonadIO m => CanReadFile (m LByteString) where
     readFile = liftIO . L.readFile . F.encodeString
 instance CanWriteFileFunc LByteString where
@@ -66,3 +68,10 @@
         | x `L.isSuffixOf` y = Prelude.Just (L.take (L.length y Prelude.- L.length x) y)
         | Prelude.otherwise = Prelude.Nothing
     isSuffixOf = L.isSuffixOf
+
+instance CanToStrict LByteString Data.ByteString.ByteString where
+    toStrict = Data.ByteString.concat . toChunks
+    fromStrict = fromChunks . Prelude.return
+
+instance CanPartition LByteString Word8 where
+    partition = L.partition
diff --git a/ClassyPrelude/LText.hs b/ClassyPrelude/LText.hs
--- a/ClassyPrelude/LText.hs
+++ b/ClassyPrelude/LText.hs
@@ -15,6 +15,9 @@
 import qualified Data.Text.Lazy.Encoding
 import qualified Data.Text.Encoding.Error
 import Data.ByteString.Lazy (ByteString)
+import qualified Data.Text.Lazy.IO as TL
+import Control.Monad.IO.Class (MonadIO, liftIO)
+import qualified Filesystem.Path.CurrentOS as F
 
 type LText = TL.Text
 
@@ -31,6 +34,8 @@
 instance CanPack LText Prelude.Char where
     pack = TL.pack
     unpack = TL.unpack
+instance CanIntersperse LText Prelude.Char where
+    intersperse = TL.intersperse
 instance CanStripPrefix LText where
     stripPrefix = TL.stripPrefix
     isPrefixOf = TL.isPrefixOf
@@ -85,3 +90,25 @@
     encodeUtf8Func = Data.Text.Lazy.Encoding.encodeUtf8
 instance CanDecodeUtf8Func ByteString LText where
     decodeUtf8Func = Data.Text.Lazy.Encoding.decodeUtf8With Data.Text.Encoding.Error.lenientDecode
+
+instance CanToStrict LText Data.Text.Text where
+    toStrict = TL.toStrict
+    fromStrict = TL.fromStrict
+
+instance MonadIO m => CanGetLine (m LText) where
+    getLine = liftIO TL.getLine
+
+instance CanToLower LText where
+    toLower = TL.toLower
+
+instance CanToUpper LText where
+    toUpper = TL.toUpper
+
+instance CanToCaseFold LText where
+    toCaseFold = TL.toCaseFold
+
+instance CanFind LText Prelude.Char where
+    find = TL.find
+
+instance CanPartition LText Prelude.Char where
+    partition = TL.partition
diff --git a/ClassyPrelude/List.hs b/ClassyPrelude/List.hs
--- a/ClassyPrelude/List.hs
+++ b/ClassyPrelude/List.hs
@@ -5,11 +5,15 @@
 module ClassyPrelude.List () where
 
 import qualified Prelude
-import Prelude ((.))
+import Prelude ((.), otherwise)
 import ClassyPrelude.Classes
 import qualified Data.List
 import qualified Control.Monad
 
+import Data.Monoid (Monoid)
+import qualified Data.Monoid as Monoid
+import qualified Data.Set as Set
+
 instance CanMapFunc [a] [b] a b where
     mapFunc = Prelude.map
 instance CanConcatMapFunc [a] [b] a [b] where
@@ -27,6 +31,10 @@
 instance CanPack [a] a where
     pack = Prelude.id
     unpack = Prelude.id
+    subsequences = Data.List.subsequences
+    permutations = Data.List.permutations
+instance CanIntersperse [a] a where
+    intersperse = Data.List.intersperse
 instance Prelude.Monad m => CanMapMFunc [i] (m [o]) m i o where
     mapMFunc = Prelude.mapM
 instance CanMapM_Func [a] a where
@@ -76,3 +84,23 @@
 
 instance CanReplicateM [a] a Prelude.Int where
     replicateM = Control.Monad.replicateM
+
+instance CanFind [a] a where
+    find = Data.List.find
+
+instance (Monoid m) => CanConcat [m] m where
+    concat = Monoid.mconcat
+
+instance CanPartition [a] a where
+    partition = Data.List.partition
+
+instance CanNubBy [a] a where
+    nubBy = Data.List.nubBy
+
+    nub =
+        go Set.empty
+      where
+        go _ [] = []
+        go set (x:xs)
+            | x `Set.member` set = go set xs
+            | otherwise = x : go (Set.insert x set) xs
diff --git a/ClassyPrelude/Map.hs b/ClassyPrelude/Map.hs
--- a/ClassyPrelude/Map.hs
+++ b/ClassyPrelude/Map.hs
@@ -12,6 +12,11 @@
 import Data.Map (Map)
 import qualified Data.Map as Map
 
+import Data.Monoid (Monoid)
+import qualified Data.Monoid as Monoid
+import Data.Foldable (Foldable)
+import qualified Data.Foldable as Foldable
+
 instance CanMapFunc (Map k v1) (Map k v2) v1 v2 where
     mapFunc = Map.map
 instance Prelude.Ord k => CanFilterFunc (Map k v) (Map k v) (k, v) where
@@ -31,3 +36,9 @@
     insertVal = Map.insert
 instance Prelude.Ord k => CanDeleteVal (Map k v) k where
     deleteVal = Map.delete
+instance CanFind (Map k v) v where
+    find = Foldable.find
+instance (Monoid v) => CanConcat (Map k v) v where
+    concat = Foldable.fold
+instance Prelude.Ord k => CanPartition (Map k v) v where
+    partition = Map.partition
diff --git a/ClassyPrelude/Set.hs b/ClassyPrelude/Set.hs
--- a/ClassyPrelude/Set.hs
+++ b/ClassyPrelude/Set.hs
@@ -12,6 +12,11 @@
 import Data.Set (Set)
 import qualified Data.Set as Set
 
+import Data.Monoid (Monoid)
+import qualified Data.Monoid as Monoid
+import Data.Foldable (Foldable)
+import qualified Data.Foldable as Foldable
+
 instance (Prelude.Ord a, Prelude.Ord b) => CanMapFunc (Set a) (Set b) a b where
     mapFunc = Set.map
 instance CanLength (Set x) Prelude.Int where
@@ -33,3 +38,12 @@
 
 instance Prelude.Ord a => CanMapM_Func (Set a) a where
     mapM_Func f = Prelude.mapM_ f . unpack
+
+instance CanFind (Set a) a where
+    find = Foldable.find
+
+instance (Monoid m) => CanConcat (Set m) m where
+    concat = Foldable.fold
+
+instance (Prelude.Ord a) => CanPartition (Set a) a where
+    partition = Set.partition
diff --git a/ClassyPrelude/Text.hs b/ClassyPrelude/Text.hs
--- a/ClassyPrelude/Text.hs
+++ b/ClassyPrelude/Text.hs
@@ -14,6 +14,9 @@
 import qualified Data.Text.Encoding
 import qualified Data.Text.Encoding.Error
 import Data.ByteString (ByteString)
+import qualified Data.Text.IO as T
+import Control.Monad.IO.Class (MonadIO, liftIO)
+import qualified Filesystem.Path.CurrentOS as F
 
 instance CanMapFunc Text Text Char Char where
     mapFunc = T.map
@@ -30,6 +33,8 @@
 instance CanPack Text Prelude.Char where
     pack = T.pack
     unpack = T.unpack
+instance CanIntersperse Text Prelude.Char where
+    intersperse = T.intersperse
 instance CanStripPrefix Text where
     stripPrefix = T.stripPrefix
     isPrefixOf = T.isPrefixOf
@@ -77,3 +82,21 @@
     encodeUtf8Func = Data.Text.Encoding.encodeUtf8
 instance CanDecodeUtf8Func ByteString Text where
     decodeUtf8Func = Data.Text.Encoding.decodeUtf8With Data.Text.Encoding.Error.lenientDecode
+
+instance MonadIO m => CanGetLine (m Text) where
+    getLine = liftIO T.getLine
+
+instance CanToLower Text where
+    toLower = T.toLower
+
+instance CanToUpper Text where
+    toUpper = T.toUpper
+
+instance CanToCaseFold Text where
+    toCaseFold = T.toCaseFold
+
+instance CanFind Text Prelude.Char where
+    find = T.find
+
+instance CanPartition Text Prelude.Char where
+    partition = T.partition
diff --git a/ClassyPrelude/Vector.hs b/ClassyPrelude/Vector.hs
--- a/ClassyPrelude/Vector.hs
+++ b/ClassyPrelude/Vector.hs
@@ -7,11 +7,16 @@
     ) where
 
 import qualified Prelude
-import Prelude ((.))
+import Prelude ((.), ($))
 import ClassyPrelude.Classes
 import Data.Vector (Vector)
 import qualified Data.Vector as V
 
+import Data.Monoid (Monoid)
+import qualified Data.Monoid as Monoid
+import Data.Foldable (Foldable)
+import qualified Data.Foldable as Foldable
+
 instance CanMapFunc (Vector a) (Vector b) a b where
     mapFunc = V.map
 instance CanConcatMapFunc (Vector a) (Vector b) a (Vector b) where
@@ -29,6 +34,13 @@
 instance CanPack (Vector a) a where
     pack = V.fromList
     unpack = V.toList
+instance CanIntersperse (Vector a) a where
+    -- | Implementation is a rip off from <http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/Data-List.html#intersperse>.
+    intersperse _ xs | null xs = V.empty
+    intersperse sep xs = V.cons (V.head xs) $ prependToAll sep $ V.unsafeTail xs
+      where
+        prependToAll _ xs | null xs = V.empty
+        prependToAll sep xs = V.cons sep $ V.cons (V.head xs) $ prependToAll sep $ V.unsafeTail xs
 instance Prelude.Monad m => CanMapMFunc (Vector i) (m (Vector o)) m i o where
     mapMFunc = V.mapM
 instance CanMapM_Func (Vector a) a where
@@ -56,3 +68,12 @@
 
 instance CanReplicateM (Vector a) a Prelude.Int where
     replicateM = V.replicateM
+
+instance CanFind (Vector a) a where
+    find = V.find
+    
+instance (Monoid m) => CanConcat (Vector m) m where
+    concat = Foldable.fold
+
+instance CanPartition (Vector a) a where
+    partition = V.partition
diff --git a/classy-prelude.cabal b/classy-prelude.cabal
--- a/classy-prelude.cabal
+++ b/classy-prelude.cabal
@@ -1,5 +1,5 @@
 name:                classy-prelude
-version:             0.4.3
+version:             0.4.4
 synopsis:            A typeclass-based Prelude.
 description:         Focuses on using common typeclasses when possible, and creating new ones to avoid name clashing. Exposes many recommended datastructures (Map, ByteString, etc) directly without requiring long import lists and qualified modules.
 homepage:            https://github.com/snoyberg/classy-prelude
@@ -35,6 +35,7 @@
                      , vector
                      , unordered-containers
                      , hashable
+                     , lifted-base
   ghc-options:         -Wall -fno-warn-orphans
 
 test-suite test
