diff --git a/ClassyPrelude.hs b/ClassyPrelude.hs
--- a/ClassyPrelude.hs
+++ b/ClassyPrelude.hs
@@ -66,18 +66,33 @@
     , partition
     , nub
     , nubBy
+    , sort
+    , sortBy
+    , sortWith
+    , cons
+    , uncons
       -- ** Map-like
     , lookup
     , insert
     , delete
       -- ** Set-like
     , member
+    , notMember
     , elem
+    , notElem
+    , union
+    , difference
+    , (\\)
+    , intersection
+    , intersect
+    , unions
       -- ** Text-like
     , show
     , toLower
     , toUpper
     , toCaseFold
+    , toStrict
+    , fromStrict
       -- ** IO
     , readFile
     , writeFile
@@ -87,6 +102,7 @@
     , toChunks
     , fromChunks
       -- ** Force types
+      -- | Helper functions for situations where type inferer gets confused.
     , asByteString
     , asLByteString
     , asHashMap
@@ -95,20 +111,25 @@
     , asLText
     , asList
     , asMap
+    , asMaybe
     , asSet
     , asVector
     ) where
 
 import qualified Prelude
-import qualified Data.Maybe
 import Control.Monad (when, unless, void, liftM, ap, forever, join, sequence, sequence_)
 import Control.Concurrent.MVar.Lifted
 import Data.IORef.Lifted
+import Data.Monoid (Monoid)
+import qualified Data.Monoid as Monoid
+import Data.Foldable (Foldable)
+import qualified Data.Foldable as Foldable
 
 import CorePrelude hiding (print)
 import ClassyPrelude.Classes
 
 import ClassyPrelude.ByteString ()
+import ClassyPrelude.Char ()
 import ClassyPrelude.Classes ()
 import ClassyPrelude.FilePath ()
 import ClassyPrelude.HashMap ()
@@ -117,11 +138,13 @@
 import ClassyPrelude.LText ()
 import ClassyPrelude.List ()
 import ClassyPrelude.Map ()
+import ClassyPrelude.Maybe ()
 import ClassyPrelude.Set ()
 import ClassyPrelude.Text ()
 import ClassyPrelude.Vector ()
 
-show :: (Prelude.Show a, CanPack c Char) => a -> c
+
+show :: (Show a, CanPack c Char) => a -> c
 show = pack . Prelude.show
 
 fromList :: CanPack c i => [i] -> c
@@ -130,12 +153,7 @@
 toList :: CanPack c i => c -> [i]
 toList = unpack
 
--- Misc instances
-instance CanPack (Prelude.Maybe a) a where
-    pack = Data.Maybe.listToMaybe
-    unpack = Data.Maybe.maybeToList
-
-readMay :: (Prelude.Read b, CanPack a Char) => a -> Maybe b
+readMay :: (Read b, CanPack a Char) => a -> Maybe b
 readMay a =
     case [x | (x, t) <- Prelude.reads (unpack a), null t] of
         [x] -> Just x
@@ -160,6 +178,20 @@
 (++) = mappend
 {-# INLINE (++) #-}
 
+infixl 9 \\{-This comment teaches CPP correct behaviour -}
+-- | An alias for `difference`.
+(\\) :: CanDifference c => c -> c -> c
+(\\) = difference
+{-# INLINE (\\) #-}
+
+-- | An alias for `intersection`.
+intersect :: CanIntersection c => c -> c -> c
+intersect = intersection
+{-# INLINE intersect #-}
+
+unions :: (Foldable cc, Monoid c, CanUnion c) => cc c -> c
+unions = Foldable.foldl' union Monoid.mempty
+
 intercalate :: (CanConcat c i, CanIntersperse c i) => i -> c -> i
 intercalate xs xss = concat (intersperse xs xss)
 
@@ -187,20 +219,40 @@
 asMap :: Map k v -> Map k v
 asMap = id
 
+asMaybe :: Maybe a -> Maybe a
+asMaybe = id
+
 asSet :: Set a -> Set a
 asSet = id
 
 asVector :: Vector a -> Vector a
 asVector = id
 
-forM :: CanMapMFunc ci mco m i o => ci -> (i -> m o) -> mco
+forM :: CanMapM ci mco m i o => ci -> (i -> m o) -> mco
 forM = flip mapM
 
-forM_ :: (Monad m, CanMapM_Func ci i) => ci -> (i -> m o) -> m ()
+forM_ :: (Monad m, CanMapM_ ci i) => ci -> (i -> m o) -> m ()
 forM_ = flip mapM_
 
+-- | An alias for 'member'
 elem :: CanMember c k => k -> c -> Bool
 elem = member
 
+-- | An alias for 'notMember'
+notElem :: CanMember c k => k -> c -> Bool
+notElem = notMember
+
 print :: (Show a, MonadIO m) => a -> m ()
 print = liftIO . Prelude.print
+
+take :: CanSplitAt c i => i -> c -> c
+take i c  = Prelude.fst (splitAt i c)
+
+drop :: CanSplitAt c i => i -> c -> c
+drop i c  = Prelude.snd (splitAt i c)
+
+-- | Sort elements using the user supplied function to project something out of
+-- each element.
+-- Inspired by <http://hackage.haskell.org/packages/archive/base/latest/doc/html/GHC-Exts.html#v:sortWith>.
+sortWith :: (CanSortBy c a, Ord b) => (a -> b) -> c a -> c a
+sortWith f = sortBy $ comparing f
diff --git a/ClassyPrelude/ByteString.hs b/ClassyPrelude/ByteString.hs
--- a/ClassyPrelude/ByteString.hs
+++ b/ClassyPrelude/ByteString.hs
@@ -6,64 +6,79 @@
     ( ByteString
     ) where
 
-import qualified Prelude
-import Prelude ((.))
+import CorePrelude
 import ClassyPrelude.Classes
-import qualified Data.ByteString as S
-import Data.ByteString (ByteString)
-import Control.Monad.IO.Class (MonadIO, liftIO)
-import qualified Filesystem.Path.CurrentOS as F
-import Data.Word (Word8)
+import qualified Data.ByteString as ByteString
+import qualified Filesystem.Path.CurrentOS as FilePath
 
-instance CanMapFunc ByteString ByteString Word8 Word8 where
-    mapFunc = S.map
-instance CanConcatMapFunc ByteString ByteString Word8 ByteString where
-    concatMapFunc = S.concatMap
-instance CanFilterFunc ByteString ByteString Word8 where
-    filterFunc = S.filter
-instance CanLength ByteString Prelude.Int where
-    length = S.length
+
+instance CanMap ByteString ByteString Word8 Word8 where
+    map = ByteString.map
+
+instance CanConcatMap ByteString ByteString Word8 ByteString where
+    concatMap = ByteString.concatMap
+
+instance CanFilter ByteString Word8 where
+    filter = ByteString.filter
+
+instance CanLength ByteString Int where
+    length = ByteString.length
+
 instance CanSingleton ByteString Word8 where
-    singleton = S.singleton
+    singleton = ByteString.singleton
+
 instance CanNull ByteString where
-    null = S.null
+    null = ByteString.null
+
 instance CanPack ByteString Word8 where
-    pack = S.pack
-    unpack = S.unpack
+    pack = ByteString.pack
+    unpack = ByteString.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
-    writeFileFunc fp = liftIO . S.writeFile (F.encodeString fp)
+    intersperse = ByteString.intersperse
+
+instance CanReadFile ByteString where
+    readFile = liftIO . ByteString.readFile . FilePath.encodeString
+
+instance CanWriteFile ByteString where
+    writeFile fp = liftIO . ByteString.writeFile (FilePath.encodeString fp)
+
 instance CanBreak ByteString Word8 where
-    break = S.break
-    span = S.span
-    dropWhile = S.dropWhile
-    takeWhile = S.takeWhile
+    break = ByteString.break
+    span = ByteString.span
+    dropWhile = ByteString.dropWhile
+    takeWhile = ByteString.takeWhile
+
 instance CanAny ByteString Word8 where
-    any = S.any
-    all = S.all
-instance CanSplitAt ByteString Prelude.Int where
-    splitAt = S.splitAt
+    any = ByteString.any
+    all = ByteString.all
 
+instance CanSplitAt ByteString Int where
+    splitAt = ByteString.splitAt
+
 instance CanReverse ByteString where
-    reverse = S.reverse
+    reverse = ByteString.reverse
 
-instance CanFoldFunc ByteString Word8 accum where
-    foldFunc = S.foldl'
+instance CanFold ByteString Word8 accum where
+    fold = ByteString.foldl'
 
-instance CanReplicate ByteString Word8 Prelude.Int where
-    replicate = S.replicate
+instance CanReplicate ByteString Word8 Int where
+    replicate = ByteString.replicate
 
 instance CanStripSuffix ByteString where
     stripSuffix x y
-        | x `S.isSuffixOf` y = Prelude.Just (S.take (S.length y Prelude.- S.length x) y)
-        | Prelude.otherwise = Prelude.Nothing
-    isSuffixOf = S.isSuffixOf
+        | x `ByteString.isSuffixOf` y = Just (ByteString.take (ByteString.length y - ByteString.length x) y)
+        | otherwise = Nothing
+    isSuffixOf = ByteString.isSuffixOf
 
 instance MonadIO m => CanGetLine (m ByteString) where
-    getLine = liftIO S.getLine
+    getLine = liftIO ByteString.getLine
 
 instance CanPartition ByteString Word8 where
-    partition = S.partition
+    partition = ByteString.partition
+
+instance CanCons ByteString Word8 where
+    cons = ByteString.cons
+
+instance CanUncons ByteString Word8 where
+    uncons = ByteString.uncons
diff --git a/ClassyPrelude/Char.hs b/ClassyPrelude/Char.hs
new file mode 100644
--- /dev/null
+++ b/ClassyPrelude/Char.hs
@@ -0,0 +1,15 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TypeFamilies #-}
+module ClassyPrelude.Char where
+
+import CorePrelude
+import ClassyPrelude.Classes
+import qualified Data.Char as Char
+
+instance CanToLower Char where
+    toLower = Char.toLower
+
+instance CanToUpper Char where
+    toUpper = Char.toUpper
diff --git a/ClassyPrelude/Classes.hs b/ClassyPrelude/Classes.hs
--- a/ClassyPrelude/Classes.hs
+++ b/ClassyPrelude/Classes.hs
@@ -3,41 +3,25 @@
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE DefaultSignatures #-}
 module ClassyPrelude.Classes where
 
-import qualified Prelude
-import Prelude (Monad, (.), ($))
-import qualified Data.List
-import qualified Filesystem.Path.CurrentOS as F
-import Control.Monad.IO.Class (MonadIO)
+import CorePrelude
+import qualified Data.List as List
 
-class CanMap f i o where
-    map :: (i -> o) -> f
-class CanMapFunc ci co i o | ci -> i, co -> o, ci o -> co, co i -> ci where
-    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
-    concatMapFunc :: (i -> o) -> ci -> co
-instance CanConcatMapFunc ci co i o => CanConcatMap (ci -> co) i o where
-    concatMap = concatMapFunc
 
-class CanFilter f i where
-    filter :: (i -> Prelude.Bool) -> f
-class CanFilterFunc ci co i | ci -> i co where
-    filterFunc :: (i -> Prelude.Bool) -> ci -> co
-instance (CanFilterFunc ci co i, ci ~ co) => CanFilter (ci -> co) i where
-    filter = filterFunc
+class CanMap ci co i o | ci -> i, co -> o, ci o -> co, co i -> ci where
+    map :: (i -> o) -> ci -> co
 
-class CanFilterM f m i where
-    filterM :: (i -> m Prelude.Bool) -> f
-class CanFilterMFunc c i | c -> i where
-    filterMFunc :: Monad m => (i -> m Prelude.Bool) -> c -> m c
-instance (CanFilterMFunc ci i, m ci ~ mco, Monad m) => CanFilterM (ci -> mco) m i where
-    filterM = filterMFunc
+class CanConcatMap ci co i o | ci -> i, co -> o, ci o -> co, co i -> ci where
+    concatMap :: (i -> o) -> ci -> co
 
+class CanFilter c i | c -> i where
+    filter :: (i -> Bool) -> c -> c
+
+class CanFilterM c i | c -> i where
+    filterM :: Monad m => (i -> m Bool) -> c -> m c
+
 class CanLength c len | c -> len where
     length :: c -> len
 
@@ -45,120 +29,100 @@
     singleton :: i -> c
 
 class CanNull c where
-    null :: c -> Prelude.Bool
+    null :: c -> Bool
 
 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
+    subsequences = List.map pack . List.subsequences . unpack
     permutations :: c -> [c]
-    permutations = Data.List.map pack . Data.List.permutations . unpack
+    permutations = List.map pack . 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
-    mapMFunc :: (i -> m o) -> ci -> mco
-instance CanMapMFunc ci mco m i o => CanMapM (ci -> mco) m i o where
-    mapM = mapMFunc
+class Monad m => CanMapM ci mco m i o | ci -> i, mco -> m o, ci o m -> mco, mco i -> ci where
+    mapM :: (i -> m o) -> ci -> mco
 
-class Monad m => CanMapM_ f m i where
-    mapM_ :: (i -> m o) -> f
-class CanMapM_Func ci i | ci -> i where
-    mapM_Func :: Monad m => (i -> m o) -> ci -> m ()
-instance (Monad m, CanMapM_Func ci i, r ~ m ()) => CanMapM_ (ci -> r) m i where
-    mapM_ = mapM_Func
+class CanMapM_ ci i | ci -> i where
+    mapM_ :: Monad m => (i -> m o) -> ci -> m ()
 
 class CanReplicateM c i len | c -> i len where
     replicateM :: Monad m => len -> m i -> m c
 
 class CanLookup c k v | c -> k v where
-    lookup :: k -> c -> Prelude.Maybe v
+    lookup :: k -> c -> Maybe v
 
 class CanInsert f where
     insert :: f
+
 class CanInsertVal c k v | c -> k v where
     insertVal :: k -> v -> c -> c
+
 instance (CanInsertVal c' k v, c ~ c') => CanInsert (k -> v -> c -> c') where
     insert = insertVal
 
 class CanDelete f where
     delete :: f
+
 class CanDeleteVal c k | c -> k where
     deleteVal :: k -> c -> c
+
 instance (CanDeleteVal c' k, c ~ c') => CanDelete (k -> c -> c') where
     delete = deleteVal
 
 class CanMember c k | c -> k where
-    member :: k -> c -> Prelude.Bool
+    member :: k -> c -> Bool
+    notMember :: k -> c -> Bool
+    notMember k = not . member k
 
 class CanReadFile a where
-    readFile :: F.FilePath -> a
+    readFile :: MonadIO m => FilePath -> m a
 
 class CanWriteFile a where
-    writeFile :: F.FilePath -> a
-class CanWriteFileFunc a where
-    writeFileFunc :: MonadIO m => F.FilePath -> a -> m ()
-instance (MonadIO m, b ~ (), CanWriteFileFunc a) => CanWriteFile (a -> m b) where
-    writeFile = writeFileFunc
+    writeFile :: MonadIO m => FilePath -> a -> m ()
 
 class CanStripPrefix a where
-    stripPrefix :: a -> a -> Prelude.Maybe a
-    isPrefixOf :: a -> a -> Prelude.Bool
+    stripPrefix :: a -> a -> Maybe a
+    isPrefixOf :: a -> a -> Bool
 
 class CanBreak c i | c -> i where
-    break :: (i -> Prelude.Bool) -> c -> (c, c)
-    span :: (i -> Prelude.Bool) -> c -> (c, c)
-    dropWhile :: (i -> Prelude.Bool) -> c -> c
-    takeWhile :: (i -> Prelude.Bool) -> c -> c
+    break :: (i -> Bool) -> c -> (c, c)
+    span :: (i -> Bool) -> c -> (c, c)
+    dropWhile :: (i -> Bool) -> c -> c
+    takeWhile :: (i -> Bool) -> c -> c
 
 class CanAny c i | c -> i where
-    any :: (i -> Prelude.Bool) -> c -> Prelude.Bool
-    all :: (i -> Prelude.Bool) -> c -> Prelude.Bool
+    any :: (i -> Bool) -> c -> Bool
+    all :: (i -> Bool) -> c -> Bool
 
 class CanSplitAt c i | c -> i where
     splitAt :: i -> c -> (c, c)
 
-take :: CanSplitAt c i => i -> c -> c
-take i c  = Prelude.fst (splitAt i c)
-drop :: CanSplitAt c i => i -> c -> c
-drop i c  = Prelude.snd (splitAt i c)
-
-class CanFold f i accum where
-    -- | Strict left fold.
-    fold :: (accum -> i -> accum) -> accum -> f
-class CanFoldFunc c i accum | c -> i where
+class CanFold c i accum | c -> i where
     -- | Strict left fold.
-    foldFunc :: (accum -> i -> accum) -> accum -> c -> accum
-instance (CanFoldFunc c i accum, accum ~ result) => CanFold (c -> result) i accum where
-    fold = foldFunc
+    fold :: (accum -> i -> accum) -> accum -> c -> accum
 
 class CanWords t where
     words :: t -> [t]
     unwords :: [t] -> t
 
-class CanLines f where
-    lines :: f
-class CanLinesFunc t where
-    linesFunc :: t -> [t]
-instance (CanLinesFunc t, out ~ [t]) => CanLines (t -> out) where
-    lines = linesFunc
+class CanLines t where
+    lines :: t -> [t]
 
 class CanUnlines t where
     unlines :: [t] -> t
 
 class CanSplit c i | c -> i where
-    split :: (i -> Prelude.Bool) -> c -> [c]
+    split :: (i -> Bool) -> c -> [c]
 
 class CanStripSuffix a where
-    stripSuffix :: a -> a -> Prelude.Maybe a
-    isSuffixOf :: a -> a -> Prelude.Bool
+    stripSuffix :: a -> a -> Maybe a
+    isSuffixOf :: a -> a -> Bool
 
 class CanIsInfixOf a where
-    isInfixOf :: a -> a -> Prelude.Bool
+    isInfixOf :: a -> a -> Bool
 
 class CanReverse a where
     reverse :: a -> a
@@ -170,22 +134,14 @@
     toChunks :: c -> [i]
     fromChunks :: [i] -> c
 
-class CanEncodeUtf8 f where
-    encodeUtf8 :: f
-class CanEncodeUtf8Func ci co | co -> ci, ci -> co where
-    encodeUtf8Func :: ci -> co
-instance CanEncodeUtf8Func ci co => CanEncodeUtf8 (ci -> co) where
-    encodeUtf8 = encodeUtf8Func
+class CanEncodeUtf8 ci co | co -> ci, ci -> co where
+    encodeUtf8 :: ci -> co
 
-class CanDecodeUtf8 f where
-    decodeUtf8 :: f
--- | Note: implementations should ensure that @decodeUtf8Func@ is a total
+-- | Note: implementations should ensure that @decodeUtf8@ is a total
 -- function. As such, the standard @decodeUtf8@ provided by the text package
 -- should not be used, but instead @decodeUtf8With lenientDecode@.
-class CanDecodeUtf8Func ci co | co -> ci, ci -> co where
-    decodeUtf8Func :: ci -> co
-instance CanDecodeUtf8Func ci co => CanDecodeUtf8 (ci -> co) where
-    decodeUtf8 = decodeUtf8Func
+class CanDecodeUtf8 ci co | co -> ci, ci -> co where
+    decodeUtf8 :: ci -> co
 
 class CanToStrict a b where
     toStrict :: a -> b
@@ -204,16 +160,37 @@
     toCaseFold :: a -> a
 
 class CanFind c i | c -> i where
-    find :: (i -> Prelude.Bool) -> c -> Prelude.Maybe i
+    find :: (i -> Bool) -> c -> 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)
+    partition :: (i -> Bool) -> c -> (c, c)
 
 class CanNubBy c i | c -> i where
-    nubBy :: (i -> i -> Prelude.Bool) -> c -> c
+    nubBy :: (i -> i -> Bool) -> c -> c
 
-    nub :: (Prelude.Ord i, CanNubBy c i) => c -> c
-    nub = nubBy (Prelude.==)
+    nub :: (Ord i, CanNubBy c i) => c -> c
+    nub = nubBy (==)
+
+class CanUnion c where
+    union :: c -> c -> c
+
+class CanDifference c where
+    difference :: c -> c -> c
+
+class CanIntersection c where
+    intersection :: c -> c -> c
+
+class CanSortBy c a where
+    sortBy :: (a -> a -> Ordering) -> c a -> c a
+    sort :: c a -> c a
+    default sort :: (Ord a) => c a -> c a
+    sort = sortBy compare
+
+class CanCons c a where
+    cons :: a -> c -> c
+
+class CanUncons c a where
+    uncons :: c -> Maybe (a, c)
diff --git a/ClassyPrelude/FilePath.hs b/ClassyPrelude/FilePath.hs
--- a/ClassyPrelude/FilePath.hs
+++ b/ClassyPrelude/FilePath.hs
@@ -4,20 +4,22 @@
 {-# LANGUAGE TypeFamilies #-}
 module ClassyPrelude.FilePath () where
 
-import qualified Prelude
-import Prelude ((.), Char)
+import CorePrelude
 import ClassyPrelude.Classes
-import qualified Data.List
-import qualified Filesystem.Path.CurrentOS as F
+import qualified Data.List as List
+import qualified Filesystem.Path.CurrentOS as FilePath
 
-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
+
+instance CanPack FilePath Char where
+    pack = FilePath.decodeString
+    unpack = FilePath.encodeString
+
+instance CanIntersperse FilePath Char where
+    intersperse c = pack . List.intersperse c . unpack
+
+instance CanStripPrefix FilePath where
+    stripPrefix = FilePath.stripPrefix
     isPrefixOf a b =
         case stripPrefix a b of
-            Prelude.Nothing -> Prelude.False
-            Prelude.Just{} -> Prelude.True
+            Nothing -> False
+            Just {} -> True
diff --git a/ClassyPrelude/HashMap.hs b/ClassyPrelude/HashMap.hs
--- a/ClassyPrelude/HashMap.hs
+++ b/ClassyPrelude/HashMap.hs
@@ -6,42 +6,54 @@
     ( HashMap
     ) where
 
-import qualified Prelude
-import Prelude ((.), Char)
+import CorePrelude
 import ClassyPrelude.Classes
-import Data.HashMap.Strict (HashMap)
-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
+import qualified Data.HashMap.Strict as HashMap
 
-type Map = HashMap
 
-instance CanMapFunc (Map k v1) (Map k v2) v1 v2 where
-    mapFunc = Map.map
-instance Hashable k => CanFilterFunc (Map k v) (Map k v) (k, v) where
-    filterFunc = Map.filterWithKey . Prelude.curry
-instance CanLength (Map k v) Prelude.Int where
-    length = Map.size
-instance (Prelude.Eq k, Hashable k, v' ~ v) => CanSingleton (v' -> Map k v) k where
-    singleton = Map.singleton
-instance CanNull (Map k v) where
-    null = Map.null
-instance (Prelude.Eq k, Hashable k) => CanPack (Map k v) (k, v) where
-    pack = Map.fromList
-    unpack = Map.toList
-instance (Prelude.Eq k, Hashable k) => CanLookup (Map k v) k v where
-    lookup = Map.lookup
-instance (Prelude.Eq k, Hashable k) => CanInsertVal (Map k v) k v where
-    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
+instance CanMap (HashMap k v1) (HashMap k v2) v1 v2 where
+    map = HashMap.map
+    
+instance Hashable k => CanFilter (HashMap k v) (k, v) where
+    filter = HashMap.filterWithKey . curry
+    
+instance CanLength (HashMap k v) Int where
+    length = HashMap.size
+    
+instance (Eq k, Hashable k, v' ~ v) => CanSingleton (v' -> HashMap k v) k where
+    singleton = HashMap.singleton
+    
+instance CanNull (HashMap k v) where
+    null = HashMap.null
+    
+instance (Eq k, Hashable k) => CanPack (HashMap k v) (k, v) where
+    pack = HashMap.fromList
+    unpack = HashMap.toList
+    
+instance (Eq k, Hashable k) => CanLookup (HashMap k v) k v where
+    lookup = HashMap.lookup
+    
+instance (Eq k, Hashable k) => CanInsertVal (HashMap k v) k v where
+    insertVal = HashMap.insert
+    
+instance (Eq k, Hashable k) => CanDeleteVal (HashMap k v) k where
+    deleteVal = HashMap.delete
+    
+instance CanFind (HashMap k v) v where
     find = Foldable.find
-instance (Monoid v) => CanConcat (Map k v) v where
+    
+instance (Monoid v) => CanConcat (HashMap 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)
+    
+instance Hashable k => CanPartition (HashMap k v) v where
+    partition p m = (HashMap.filter p m, HashMap.filter (not . p) m)
+
+instance (Hashable k, Eq k) => CanUnion (HashMap k a) where
+    union = HashMap.union
+
+instance (Hashable k, Eq k) => CanDifference (HashMap k a) where
+    difference = HashMap.difference
+
+instance (Hashable k, Eq k) => CanIntersection (HashMap k a) where
+    intersection = HashMap.intersection
diff --git a/ClassyPrelude/HashSet.hs b/ClassyPrelude/HashSet.hs
--- a/ClassyPrelude/HashSet.hs
+++ b/ClassyPrelude/HashSet.hs
@@ -6,33 +6,45 @@
     ( HashSet
     ) where
 
-import qualified Prelude
-import Prelude ((.), Char, Eq)
+import CorePrelude
 import ClassyPrelude.Classes
-import Data.HashSet (HashSet)
-import qualified Data.HashSet as Set
-import Data.Hashable (Hashable)
+import qualified Data.HashSet as HashSet
+import qualified Control.Monad as Monad
 
-type Set = HashSet
 
-instance (Eq b, Hashable b) => CanMapFunc (Set a) (Set b) a b where
-    mapFunc = Set.map
-instance CanLength (Set x) Prelude.Int where
-    length = Set.size
-instance Hashable x => CanSingleton (Set x) x where
-    singleton = Set.singleton
-instance CanNull (Set x) where
-    null = Set.null
-instance (Hashable x, Eq x) => CanPack (Set x) x where
-    pack = Set.fromList
-    unpack = Set.toList
-instance (Eq x, Hashable x, Set x ~ s, x ~ x') => CanInsert (x' -> s -> Set x) where
-    insert = Set.insert
-instance (Eq x, Hashable x) => CanMember (Set x) x where
-    member = Set.member
+instance (Eq b, Hashable b) => CanMap (HashSet a) (HashSet b) a b where
+    map = HashSet.map
+    
+instance CanLength (HashSet x) Int where
+    length = HashSet.size
 
-instance CanFoldFunc (Set a) a accum where
-    foldFunc = Set.foldl'
+instance Hashable x => CanSingleton (HashSet x) x where
+    singleton = HashSet.singleton
 
-instance (Eq a, Hashable a) => CanMapM_Func (HashSet a) a where
-    mapM_Func f = Prelude.mapM_ f . unpack
+instance CanNull (HashSet x) where
+    null = HashSet.null
+
+instance (Hashable x, Eq x) => CanPack (HashSet x) x where
+    pack = HashSet.fromList
+    unpack = HashSet.toList
+
+instance (Eq x, Hashable x, HashSet x ~ s, x ~ x') => CanInsert (x' -> s -> HashSet x) where
+    insert = HashSet.insert
+
+instance (Eq x, Hashable x) => CanMember (HashSet x) x where
+    member = HashSet.member
+
+instance CanFold (HashSet a) a accum where
+    fold = HashSet.foldl'
+
+instance (Eq a, Hashable a) => CanMapM_ (HashSet a) a where
+    mapM_ f = Monad.mapM_ f . unpack
+
+instance (Eq a, Hashable a) => CanUnion (HashSet a) where
+    union = HashSet.union
+
+instance (Eq a, Hashable a) => CanDifference (HashSet a) where
+    difference = HashSet.difference
+
+instance (Eq a, Hashable a) => CanIntersection (HashSet a) where
+    intersection = HashSet.intersection
diff --git a/ClassyPrelude/LByteString.hs b/ClassyPrelude/LByteString.hs
--- a/ClassyPrelude/LByteString.hs
+++ b/ClassyPrelude/LByteString.hs
@@ -6,72 +6,85 @@
     ( LByteString
     ) where
 
-import qualified Prelude
-import Prelude ((.))
+import CorePrelude
 import ClassyPrelude.Classes
-import qualified Data.ByteString.Lazy as L
-import Control.Monad.IO.Class (MonadIO, liftIO)
-import qualified Filesystem.Path.CurrentOS as F
-import Data.Word (Word8)
-import Data.Int (Int64)
-import qualified Data.ByteString
+import qualified Data.ByteString as ByteString
+import qualified Filesystem.Path.CurrentOS as FilePath
+import qualified Data.ByteString.Lazy as LByteString
 
-type LByteString = L.ByteString
 
-instance CanMapFunc LByteString LByteString Word8 Word8 where
-    mapFunc = L.map
-instance CanConcatMapFunc LByteString LByteString Word8 LByteString where
-    concatMapFunc = L.concatMap
-instance CanFilterFunc LByteString LByteString Word8 where
-    filterFunc = L.filter
+instance CanMap LByteString LByteString Word8 Word8 where
+    map = LByteString.map
+
+instance CanConcatMap LByteString LByteString Word8 LByteString where
+    concatMap = LByteString.concatMap
+
+instance CanFilter LByteString Word8 where
+    filter = LByteString.filter
+
 instance CanLength LByteString Int64 where
-    length = L.length
+    length = LByteString.length
+
 instance CanSingleton LByteString Word8 where
-    singleton = L.singleton
+    singleton = LByteString.singleton
+
 instance CanNull LByteString where
-    null = L.null
+    null = LByteString.null
+
 instance CanPack LByteString Word8 where
-    pack = L.pack
-    unpack = L.unpack
+    pack = LByteString.pack
+    unpack = LByteString.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
-    writeFileFunc fp = liftIO . L.writeFile (F.encodeString fp)
+    intersperse = LByteString.intersperse
+
+instance CanReadFile LByteString where
+    readFile = liftIO . LByteString.readFile . FilePath.encodeString
+
+instance CanWriteFile LByteString where
+    writeFile fp = liftIO . LByteString.writeFile (FilePath.encodeString fp)
+
 instance CanBreak LByteString Word8 where
-    break = L.break
-    span = L.span
-    dropWhile = L.dropWhile
-    takeWhile = L.takeWhile
+    break = LByteString.break
+    span = LByteString.span
+    dropWhile = LByteString.dropWhile
+    takeWhile = LByteString.takeWhile
+
 instance CanAny LByteString Word8 where
-    any = L.any
-    all = L.all
+    any = LByteString.any
+    all = LByteString.all
+
 instance CanSplitAt LByteString Int64 where
-    splitAt = L.splitAt
+    splitAt = LByteString.splitAt
 
 instance CanReverse LByteString where
-    reverse = L.reverse
+    reverse = LByteString.reverse
 
-instance CanFoldFunc LByteString Word8 accum where
-    foldFunc = L.foldl'
+instance CanFold LByteString Word8 accum where
+    fold = LByteString.foldl'
 
 instance CanReplicate LByteString Word8 Int64 where
-    replicate = L.replicate
+    replicate = LByteString.replicate
 
-instance CanToChunks LByteString Data.ByteString.ByteString where
-    toChunks = L.toChunks
-    fromChunks = L.fromChunks
+instance CanToChunks LByteString ByteString where
+    toChunks = LByteString.toChunks
+    fromChunks = LByteString.fromChunks
 
 instance CanStripSuffix LByteString where
     stripSuffix x y
-        | x `L.isSuffixOf` y = Prelude.Just (L.take (L.length y Prelude.- L.length x) y)
-        | Prelude.otherwise = Prelude.Nothing
-    isSuffixOf = L.isSuffixOf
+        | x `LByteString.isSuffixOf` y = Just (LByteString.take (LByteString.length y - LByteString.length x) y)
+        | otherwise = Nothing
+    isSuffixOf = LByteString.isSuffixOf
 
-instance CanToStrict LByteString Data.ByteString.ByteString where
-    toStrict = Data.ByteString.concat . toChunks
-    fromStrict = fromChunks . Prelude.return
+instance CanToStrict LByteString ByteString where
+    toStrict = ByteString.concat . toChunks
+    fromStrict = fromChunks . return
 
 instance CanPartition LByteString Word8 where
-    partition = L.partition
+    partition = LByteString.partition
+
+instance CanCons LByteString Word8 where
+    cons = LByteString.cons
+
+instance CanUncons LByteString Word8 where
+    uncons = LByteString.uncons
diff --git a/ClassyPrelude/LText.hs b/ClassyPrelude/LText.hs
--- a/ClassyPrelude/LText.hs
+++ b/ClassyPrelude/LText.hs
@@ -6,109 +6,119 @@
     ( LText
     ) where
 
-import qualified Prelude
-import Prelude ((.), Char)
+import CorePrelude
 import ClassyPrelude.Classes
-import qualified Data.Text.Lazy as TL
-import Data.Int (Int64)
-import qualified Data.Text
-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
+import qualified Data.Text.Lazy as LText
+import qualified Data.Text.Lazy.IO as LText
+import qualified Data.Text.Lazy.Encoding as LText
+import qualified Data.Text.Encoding.Error as Text
 
-type LText = TL.Text
 
-instance CanMapFunc LText LText Char Char where
-    mapFunc = TL.map
-instance CanConcatMapFunc LText LText Char LText where
-    concatMapFunc = TL.concatMap
-instance CanFilterFunc LText LText Char where
-    filterFunc = TL.filter
-instance CanSingleton LText Prelude.Char where
-    singleton = TL.singleton
+instance CanMap LText LText Char Char where
+    map = LText.map
+
+instance CanConcatMap LText LText Char LText where
+    concatMap = LText.concatMap
+
+instance CanFilter LText Char where
+    filter = LText.filter
+
+instance CanSingleton LText Char where
+    singleton = LText.singleton
+
 instance CanNull LText where
-    null = TL.null
-instance CanPack LText Prelude.Char where
-    pack = TL.pack
-    unpack = TL.unpack
-instance CanIntersperse LText Prelude.Char where
-    intersperse = TL.intersperse
+    null = LText.null
+
+instance CanPack LText Char where
+    pack = LText.pack
+    unpack = LText.unpack
+
+instance CanIntersperse LText Char where
+    intersperse = LText.intersperse
+
 instance CanStripPrefix LText where
-    stripPrefix = TL.stripPrefix
-    isPrefixOf = TL.isPrefixOf
-instance CanBreak LText Prelude.Char where
-    break = TL.break
-    span = TL.span
-    dropWhile = TL.dropWhile
-    takeWhile = TL.takeWhile
-instance CanAny LText Prelude.Char where
-    any = TL.any
-    all = TL.all
+    stripPrefix = LText.stripPrefix
+    isPrefixOf = LText.isPrefixOf
+
+instance CanBreak LText Char where
+    break = LText.break
+    span = LText.span
+    dropWhile = LText.dropWhile
+    takeWhile = LText.takeWhile
+
+instance CanAny LText Char where
+    any = LText.any
+    all = LText.all
+
 instance CanSplitAt LText Int64 where
-    splitAt = TL.splitAt
+    splitAt = LText.splitAt
 
 instance CanWords LText where
-    words = TL.words
-    unwords = TL.unwords
+    words = LText.words
+    unwords = LText.unwords
 
-instance CanLinesFunc LText where
-    linesFunc = TL.lines
+instance CanLines LText where
+    lines = LText.lines
 
 instance CanUnlines LText where
-    unlines = TL.unlines
+    unlines = LText.unlines
 
 instance CanSplit LText Char where
-    split = TL.split
+    split = LText.split
 
 instance CanStripSuffix LText where
-    stripSuffix = TL.stripSuffix
-    isSuffixOf = TL.isSuffixOf
+    stripSuffix = LText.stripSuffix
+    isSuffixOf = LText.isSuffixOf
 
 instance CanIsInfixOf LText where
-    isInfixOf = TL.isInfixOf
+    isInfixOf = LText.isInfixOf
 
 instance CanReverse LText where
-    reverse = TL.reverse
+    reverse = LText.reverse
 
 instance CanLength LText Int64 where
-    length = TL.length
+    length = LText.length
 
-instance CanFoldFunc LText Char accum where
-    foldFunc = TL.foldl'
+instance CanFold LText Char accum where
+    fold = LText.foldl'
 
 instance CanReplicate LText LText Int64 where
-    replicate = TL.replicate
+    replicate = LText.replicate
 
-instance CanToChunks LText Data.Text.Text where
-    toChunks = TL.toChunks
-    fromChunks = TL.fromChunks
+instance CanToChunks LText Text where
+    toChunks = LText.toChunks
+    fromChunks = LText.fromChunks
 
-instance CanEncodeUtf8Func LText ByteString where
-    encodeUtf8Func = Data.Text.Lazy.Encoding.encodeUtf8
-instance CanDecodeUtf8Func ByteString LText where
-    decodeUtf8Func = Data.Text.Lazy.Encoding.decodeUtf8With Data.Text.Encoding.Error.lenientDecode
+instance CanEncodeUtf8 LText LByteString where
+    encodeUtf8 = LText.encodeUtf8
 
-instance CanToStrict LText Data.Text.Text where
-    toStrict = TL.toStrict
-    fromStrict = TL.fromStrict
+instance CanDecodeUtf8 LByteString LText where
+    decodeUtf8 = LText.decodeUtf8With Text.lenientDecode
 
+instance CanToStrict LText Text where
+    toStrict = LText.toStrict
+    fromStrict = LText.fromStrict
+
 instance MonadIO m => CanGetLine (m LText) where
-    getLine = liftIO TL.getLine
+    getLine = liftIO LText.getLine
 
 instance CanToLower LText where
-    toLower = TL.toLower
+    toLower = LText.toLower
 
 instance CanToUpper LText where
-    toUpper = TL.toUpper
+    toUpper = LText.toUpper
 
 instance CanToCaseFold LText where
-    toCaseFold = TL.toCaseFold
+    toCaseFold = LText.toCaseFold
 
-instance CanFind LText Prelude.Char where
-    find = TL.find
+instance CanFind LText Char where
+    find = LText.find
 
-instance CanPartition LText Prelude.Char where
-    partition = TL.partition
+instance CanPartition LText Char where
+    partition = LText.partition
+
+instance CanCons LText Char where
+    cons = LText.cons
+
+instance CanUncons LText Char where
+    uncons = LText.uncons
diff --git a/ClassyPrelude/List.hs b/ClassyPrelude/List.hs
--- a/ClassyPrelude/List.hs
+++ b/ClassyPrelude/List.hs
@@ -4,98 +4,115 @@
 {-# LANGUAGE TypeFamilies #-}
 module ClassyPrelude.List () where
 
-import qualified Prelude
-import Prelude ((.), otherwise)
+import CorePrelude
 import ClassyPrelude.Classes
-import qualified Data.List
-import qualified Control.Monad
-
-import Data.Monoid (Monoid)
+import qualified Data.List as List
+import qualified Control.Monad as Monad
 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
-    concatMapFunc = Prelude.concatMap
-instance CanFilterFunc [a] [a] a where
-    filterFunc = Prelude.filter
-instance CanFilterMFunc [a] a where
-    filterMFunc = Control.Monad.filterM
-instance CanLength [a] Prelude.Int where
-    length = Prelude.length
+
+instance CanMap [a] [b] a b where
+    map = List.map
+
+instance CanConcatMap [a] [b] a [b] where
+    concatMap = List.concatMap
+
+instance CanFilter [a] a where
+    filter = List.filter
+
+instance CanFilterM [a] a where
+    filterM = Monad.filterM
+
+instance CanLength [a] Int where
+    length = List.length
+
 instance CanSingleton [a] a where
-    singleton = Prelude.return
+    singleton = return
+
 instance CanNull [a] where
-    null = Prelude.null
+    null = List.null
+
 instance CanPack [a] a where
-    pack = Prelude.id
-    unpack = Prelude.id
-    subsequences = Data.List.subsequences
-    permutations = Data.List.permutations
+    pack = id
+    unpack = id
+    subsequences = List.subsequences
+    permutations = 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
-    mapM_Func = Prelude.mapM_
-instance Prelude.Eq k => CanLookup [(k, v)] k v where
-    lookup = Prelude.lookup
-instance Prelude.Eq k => CanInsertVal [(k, v)] k v where
+    intersperse = List.intersperse
+
+instance Monad m => CanMapM [i] (m [o]) m i o where
+    mapM = Monad.mapM
+
+instance CanMapM_ [a] a where
+    mapM_ = Monad.mapM_
+
+instance Eq k => CanLookup [(k, v)] k v where
+    lookup = List.lookup
+
+instance Eq k => CanInsertVal [(k, v)] k v where
     insertVal k v c = (k, v) : delete k c
-instance Prelude.Eq k => CanDeleteVal [(k, v)] k where
-    deleteVal k = filter ((Prelude./= k) . Prelude.fst)
-instance Prelude.Eq x => CanMember [x] x where
-    member x = Prelude.any (Prelude.== x)
-instance Prelude.Eq a => CanStripPrefix [a] where
-    stripPrefix = Data.List.stripPrefix
-    isPrefixOf = Data.List.isPrefixOf
+
+instance Eq k => CanDeleteVal [(k, v)] k where
+    deleteVal k = filter ((/= k) . fst)
+
+instance Eq x => CanMember [x] x where
+    member x = List.any (== x)
+
+instance Eq a => CanStripPrefix [a] where
+    stripPrefix = List.stripPrefix
+    isPrefixOf = List.isPrefixOf
+
 instance CanBreak [a] a where
-    break = Prelude.break
-    span = Prelude.span
-    dropWhile = Prelude.dropWhile
-    takeWhile = Prelude.takeWhile
+    break = List.break
+    span = List.span
+    dropWhile = List.dropWhile
+    takeWhile = List.takeWhile
+
 instance CanAny [a] a where
-    any = Prelude.any
-    all = Prelude.all
-instance CanSplitAt [c] Prelude.Int where
-    splitAt = Prelude.splitAt
-instance CanFoldFunc [a] a accum where
-    foldFunc = Data.List.foldl'
+    any = List.any
+    all = List.all
 
-instance (c ~ Prelude.Char) => CanWords [c] where
-    words = Prelude.words
-    unwords = Prelude.unwords
+instance CanSplitAt [c] Int where
+    splitAt = List.splitAt
 
-instance (c ~ Prelude.Char) => CanLinesFunc [c] where
-    linesFunc = Prelude.lines
+instance CanFold [a] a accum where
+    fold = List.foldl'
 
-instance (c ~ Prelude.Char) => CanUnlines [c] where
-    unlines = Prelude.unlines
+instance (c ~ Char) => CanWords [c] where
+    words = List.words
+    unwords = List.unwords
 
-instance Prelude.Eq a => CanIsInfixOf [a] where
-    isInfixOf = Data.List.isInfixOf
+instance (c ~ Char) => CanLines [c] where
+    lines = List.lines
 
+instance (c ~ Char) => CanUnlines [c] where
+    unlines = List.unlines
+
+instance Eq a => CanIsInfixOf [a] where
+    isInfixOf = List.isInfixOf
+
 instance CanReverse [a] where
-    reverse = Prelude.reverse
+    reverse = List.reverse
 
-instance CanReplicate [i] i Prelude.Int where
-    replicate = Prelude.replicate
+instance CanReplicate [i] i Int where
+    replicate = List.replicate
 
-instance CanReplicateM [a] a Prelude.Int where
-    replicateM = Control.Monad.replicateM
+instance CanReplicateM [a] a Int where
+    replicateM = Monad.replicateM
 
 instance CanFind [a] a where
-    find = Data.List.find
+    find = List.find
 
 instance (Monoid m) => CanConcat [m] m where
     concat = Monoid.mconcat
 
 instance CanPartition [a] a where
-    partition = Data.List.partition
+    partition = List.partition
 
 instance CanNubBy [a] a where
-    nubBy = Data.List.nubBy
+    nubBy = List.nubBy
 
     nub =
         go Set.empty
@@ -104,3 +121,22 @@
         go set (x:xs)
             | x `Set.member` set = go set xs
             | otherwise = x : go (Set.insert x set) xs
+
+instance (Eq a) => CanUnion [a] where
+    union = List.union
+
+instance (Eq a) => CanDifference [a] where
+    difference = (List.\\)
+
+instance (Eq a) => CanIntersection [a] where
+    intersection = List.intersect
+
+instance (Ord a) => CanSortBy [] a where
+    sortBy = List.sortBy
+
+instance CanCons [a] a where
+    cons = (:)
+
+instance CanUncons [a] a where
+    uncons (head:tail) = Just (head, tail)
+    uncons _ = Nothing
diff --git a/ClassyPrelude/Map.hs b/ClassyPrelude/Map.hs
--- a/ClassyPrelude/Map.hs
+++ b/ClassyPrelude/Map.hs
@@ -6,39 +6,54 @@
     ( Map
     ) where
 
-import qualified Prelude
-import Prelude ((.), Char)
+import CorePrelude
 import ClassyPrelude.Classes
-import Data.Map (Map)
+import qualified Data.Foldable as Foldable
 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
-    filterFunc = Map.filterWithKey . Prelude.curry
-instance CanLength (Map k v) Prelude.Int where
+instance CanMap (Map k v1) (Map k v2) v1 v2 where
+    map = Map.map
+
+instance Ord k => CanFilter (Map k v) (k, v) where
+    filter = Map.filterWithKey . curry
+
+instance CanLength (Map k v) Int where
     length = Map.size
+
 instance (v' ~ v) => CanSingleton (v' -> Map k v) k where
     singleton = Map.singleton
+
 instance CanNull (Map k v) where
     null = Map.null
-instance Prelude.Ord k => CanPack (Map k v) (k, v) where
+
+instance Ord k => CanPack (Map k v) (k, v) where
     pack = Map.fromList
     unpack = Map.toList
-instance Prelude.Ord k => CanLookup (Map k v) k v where
+
+instance Ord k => CanLookup (Map k v) k v where
     lookup = Map.lookup
-instance Prelude.Ord k => CanInsertVal (Map k v) k v where
+
+instance Ord k => CanInsertVal (Map k v) k v where
     insertVal = Map.insert
-instance Prelude.Ord k => CanDeleteVal (Map k v) k where
+
+instance 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
+
+instance Ord k => CanPartition (Map k v) v where
     partition = Map.partition
+
+instance (Ord k) => CanUnion (Map k a) where
+    union = Map.union
+
+instance (Ord k) => CanDifference (Map k a) where
+    difference = Map.difference
+
+instance (Ord k) => CanIntersection (Map k a) where
+    intersection = Map.intersection
diff --git a/ClassyPrelude/Maybe.hs b/ClassyPrelude/Maybe.hs
new file mode 100644
--- /dev/null
+++ b/ClassyPrelude/Maybe.hs
@@ -0,0 +1,60 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE TypeFamilies #-}
+module ClassyPrelude.Maybe () where
+
+import CorePrelude
+import ClassyPrelude.Classes
+import qualified Data.Maybe as Maybe
+import qualified Control.Monad as Monad
+import qualified Data.Foldable as Foldable
+import qualified Data.Traversable as Traversable
+
+
+instance CanMap (Maybe a) (Maybe b) a b where
+  map = Monad.fmap
+
+instance CanConcatMap (Maybe a) (Maybe b) a (Maybe b) where
+  concatMap = (Monad.=<<)
+
+instance CanFilter (Maybe a) a where
+  filter = Monad.mfilter
+
+instance CanLength (Maybe a) Int where
+  length a = if null a then 0 else 1
+
+instance CanSingleton (Maybe a) a where
+  singleton = Monad.return
+
+instance CanNull (Maybe a) where
+  null = Maybe.isNothing
+
+instance CanPack (Maybe a) a where
+  pack = Maybe.listToMaybe
+  unpack = Maybe.maybeToList
+
+instance Monad m => CanMapM (Maybe i) (m (Maybe o)) m i o where
+  mapM = Traversable.mapM
+
+instance CanMapM_ (Maybe a) a where
+  mapM_ = Foldable.mapM_
+
+instance Eq x => CanMember (Maybe x) x where
+  member = Foldable.elem
+
+instance CanAny (Maybe a) a where
+  any = Foldable.any
+  all = Foldable.all
+
+instance CanFold (Maybe a) a accum where
+  fold = Foldable.foldl'
+
+instance Eq a => CanIsInfixOf (Maybe a) where
+  isInfixOf = (==)
+
+instance CanReverse (Maybe a) where
+  reverse = id
+
+instance CanFind (Maybe a) a where
+  find = Foldable.find
diff --git a/ClassyPrelude/Set.hs b/ClassyPrelude/Set.hs
--- a/ClassyPrelude/Set.hs
+++ b/ClassyPrelude/Set.hs
@@ -6,38 +6,40 @@
     ( Set
     ) where
 
-import qualified Prelude
-import Prelude ((.), Char)
+import CorePrelude
 import ClassyPrelude.Classes
-import Data.Set (Set)
+import qualified Control.Monad as Monad
+import qualified Data.Foldable as Foldable
 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
+instance (Ord a, Ord b) => CanMap (Set a) (Set b) a b where
+    map = Set.map
+
+instance CanLength (Set x) Int where
     length = Set.size
+
 instance CanSingleton (Set x) x where
     singleton = Set.singleton
+
 instance CanNull (Set x) where
     null = Set.null
-instance Prelude.Ord x => CanPack (Set x) x where
+
+instance Ord x => CanPack (Set x) x where
     pack = Set.fromList
     unpack = Set.toList
-instance (Prelude.Ord x, Set x ~ s, x ~ x') => CanInsert (x' -> s -> Set x) where
+
+instance (Ord x, Set x ~ s, x ~ x') => CanInsert (x' -> s -> Set x) where
     insert = Set.insert
-instance Prelude.Ord x => CanMember (Set x) x where
+
+instance Ord x => CanMember (Set x) x where
     member = Set.member
 
-instance CanFoldFunc (Set a) a accum where
-    foldFunc = Set.foldl'
+instance CanFold (Set a) a accum where
+    fold = Set.foldl'
 
-instance Prelude.Ord a => CanMapM_Func (Set a) a where
-    mapM_Func f = Prelude.mapM_ f . unpack
+instance Ord a => CanMapM_ (Set a) a where
+    mapM_ f = Monad.mapM_ f . unpack
 
 instance CanFind (Set a) a where
     find = Foldable.find
@@ -45,5 +47,14 @@
 instance (Monoid m) => CanConcat (Set m) m where
     concat = Foldable.fold
 
-instance (Prelude.Ord a) => CanPartition (Set a) a where
+instance (Ord a) => CanPartition (Set a) a where
     partition = Set.partition
+
+instance (Ord a) => CanUnion (Set a) where
+    union = Set.union
+
+instance (Ord a) => CanDifference (Set a) where
+    difference = Set.difference
+
+instance (Ord a) => CanIntersection (Set a) where
+    intersection = Set.intersection
diff --git a/ClassyPrelude/Text.hs b/ClassyPrelude/Text.hs
--- a/ClassyPrelude/Text.hs
+++ b/ClassyPrelude/Text.hs
@@ -6,97 +6,111 @@
     ( Text
     ) where
 
-import qualified Prelude
-import Prelude ((.), Char)
+import CorePrelude
 import ClassyPrelude.Classes
-import Data.Text (Text)
-import qualified Data.Text as T
-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
+import qualified Data.Text as Text
+import qualified Data.Text.Encoding as Text
+import qualified Data.Text.Encoding.Error as Text
+import qualified Data.Text.IO as Text
 
-instance CanMapFunc Text Text Char Char where
-    mapFunc = T.map
-instance CanConcatMapFunc Text Text Char Text where
-    concatMapFunc = T.concatMap
-instance CanFilterFunc Text Text Char where
-    filterFunc = T.filter
-instance CanLength Text Prelude.Int where
-    length = T.length
-instance CanSingleton Text Prelude.Char where
-    singleton = T.singleton
+
+instance CanMap Text Text Char Char where
+    map = Text.map
+
+instance CanConcatMap Text Text Char Text where
+    concatMap = Text.concatMap
+
+instance CanFilter Text Char where
+    filter = Text.filter
+
+instance CanLength Text Int where
+    length = Text.length
+
+instance CanSingleton Text Char where
+    singleton = Text.singleton
+
 instance CanNull Text where
-    null = T.null
-instance CanPack Text Prelude.Char where
-    pack = T.pack
-    unpack = T.unpack
-instance CanIntersperse Text Prelude.Char where
-    intersperse = T.intersperse
+    null = Text.null
+
+instance CanPack Text Char where
+    pack = Text.pack
+    unpack = Text.unpack
+
+instance CanIntersperse Text Char where
+    intersperse = Text.intersperse
+
 instance CanStripPrefix Text where
-    stripPrefix = T.stripPrefix
-    isPrefixOf = T.isPrefixOf
-instance CanBreak Text Prelude.Char where
-    break = T.break
-    span = T.span
-    dropWhile = T.dropWhile
-    takeWhile = T.takeWhile
-instance CanAny Text Prelude.Char where
-    any = T.any
-    all = T.all
-instance CanSplitAt Text Prelude.Int where
-    splitAt = T.splitAt
+    stripPrefix = Text.stripPrefix
+    isPrefixOf = Text.isPrefixOf
 
+instance CanBreak Text Char where
+    break = Text.break
+    span = Text.span
+    dropWhile = Text.dropWhile
+    takeWhile = Text.takeWhile
+
+instance CanAny Text Char where
+    any = Text.any
+    all = Text.all
+
+instance CanSplitAt Text Int where
+    splitAt = Text.splitAt
+
 instance CanWords Text where
-    words = T.words
-    unwords = T.unwords
+    words = Text.words
+    unwords = Text.unwords
 
-instance CanLinesFunc Text where
-    linesFunc = T.lines
+instance CanLines Text where
+    lines = Text.lines
 
 instance CanUnlines Text where
-    unlines = T.unlines
+    unlines = Text.unlines
 
 instance CanSplit Text Char where
-    split = T.split
+    split = Text.split
 
 instance CanStripSuffix Text where
-    stripSuffix = T.stripSuffix
-    isSuffixOf = T.isSuffixOf
+    stripSuffix = Text.stripSuffix
+    isSuffixOf = Text.isSuffixOf
 
 instance CanIsInfixOf Text where
-    isInfixOf = T.isInfixOf
+    isInfixOf = Text.isInfixOf
 
 instance CanReverse Text where
-    reverse = T.reverse
+    reverse = Text.reverse
 
-instance CanFoldFunc Text Char accum where
-    foldFunc = T.foldl'
+instance CanFold Text Char accum where
+    fold = Text.foldl'
 
-instance CanReplicate Text Text Prelude.Int where
-    replicate = T.replicate
+instance CanReplicate Text Text Int where
+    replicate = Text.replicate
 
-instance CanEncodeUtf8Func Text ByteString where
-    encodeUtf8Func = Data.Text.Encoding.encodeUtf8
-instance CanDecodeUtf8Func ByteString Text where
-    decodeUtf8Func = Data.Text.Encoding.decodeUtf8With Data.Text.Encoding.Error.lenientDecode
+instance CanEncodeUtf8 Text ByteString where
+    encodeUtf8 = Text.encodeUtf8
+    
+instance CanDecodeUtf8 ByteString Text where
+    decodeUtf8 = Text.decodeUtf8With Text.lenientDecode
 
 instance MonadIO m => CanGetLine (m Text) where
-    getLine = liftIO T.getLine
+    getLine = liftIO Text.getLine
 
 instance CanToLower Text where
-    toLower = T.toLower
+    toLower = Text.toLower
 
 instance CanToUpper Text where
-    toUpper = T.toUpper
+    toUpper = Text.toUpper
 
 instance CanToCaseFold Text where
-    toCaseFold = T.toCaseFold
+    toCaseFold = Text.toCaseFold
 
-instance CanFind Text Prelude.Char where
-    find = T.find
+instance CanFind Text Char where
+    find = Text.find
 
-instance CanPartition Text Prelude.Char where
-    partition = T.partition
+instance CanPartition Text Char where
+    partition = Text.partition
+
+instance CanCons Text Char where
+    cons = Text.cons
+
+instance CanUncons Text Char where
+    uncons = Text.uncons
diff --git a/ClassyPrelude/Vector.hs b/ClassyPrelude/Vector.hs
--- a/ClassyPrelude/Vector.hs
+++ b/ClassyPrelude/Vector.hs
@@ -6,74 +6,90 @@
     ( Vector
     ) where
 
-import qualified Prelude
-import Prelude ((.), ($))
+import CorePrelude
 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
+import qualified Data.Vector as Vector
 
-instance CanMapFunc (Vector a) (Vector b) a b where
-    mapFunc = V.map
-instance CanConcatMapFunc (Vector a) (Vector b) a (Vector b) where
-    concatMapFunc = V.concatMap
-instance CanFilterFunc (Vector a) (Vector a) a where
-    filterFunc = V.filter
-instance CanFilterMFunc (Vector a) a where
-    filterMFunc = V.filterM
-instance CanLength (Vector a) Prelude.Int where
-    length = V.length
+
+instance CanMap (Vector a) (Vector b) a b where
+    map = Vector.map
+
+instance CanConcatMap (Vector a) (Vector b) a (Vector b) where
+    concatMap = Vector.concatMap
+
+instance CanFilter (Vector a) a where
+    filter = Vector.filter
+
+instance CanFilterM (Vector a) a where
+    filterM = Vector.filterM
+
+instance CanLength (Vector a) Int where
+    length = Vector.length
+
 instance CanSingleton (Vector a) a where
-    singleton = V.singleton
+    singleton = Vector.singleton
+
 instance CanNull (Vector a) where
-    null = V.null
+    null = Vector.null
+
 instance CanPack (Vector a) a where
-    pack = V.fromList
-    unpack = V.toList
+    pack = Vector.fromList
+    unpack = Vector.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
+    intersperse _ xs | null xs = Vector.empty
+    intersperse sep xs = Vector.cons (Vector.head xs) $ prependToAll sep $ Vector.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
-    mapM_Func = V.mapM_
-instance Prelude.Eq x => CanMember (Vector x) x where
-    member x = V.any (Prelude.== x)
+        prependToAll _ xs | null xs = Vector.empty
+        prependToAll sep xs = Vector.cons sep $ Vector.cons (Vector.head xs) $ prependToAll sep $ Vector.unsafeTail xs
+
+instance Monad m => CanMapM (Vector i) (m (Vector o)) m i o where
+    mapM = Vector.mapM
+
+instance CanMapM_ (Vector a) a where
+    mapM_ = Vector.mapM_
+
+instance Eq x => CanMember (Vector x) x where
+    member x = Vector.any (== x)
+
 instance CanBreak (Vector a) a where
-    break = V.break
-    span = V.span
-    dropWhile = V.dropWhile
-    takeWhile = V.takeWhile
+    break = Vector.break
+    span = Vector.span
+    dropWhile = Vector.dropWhile
+    takeWhile = Vector.takeWhile
+
 instance CanAny (Vector a) a where
-    any = V.any
-    all = V.all
-instance CanSplitAt (Vector a) Prelude.Int where
-    splitAt = V.splitAt
-instance CanFoldFunc (Vector a) a accum where
-    foldFunc = V.foldl'
+    any = Vector.any
+    all = Vector.all
 
+instance CanSplitAt (Vector a) Int where
+    splitAt = Vector.splitAt
+
+instance CanFold (Vector a) a accum where
+    fold = Vector.foldl'
+
 instance CanReverse (Vector a) where
-    reverse = V.reverse
+    reverse = Vector.reverse
 
-instance CanReplicate (Vector a) a Prelude.Int where
-    replicate = V.replicate
+instance CanReplicate (Vector a) a Int where
+    replicate = Vector.replicate
 
-instance CanReplicateM (Vector a) a Prelude.Int where
-    replicateM = V.replicateM
+instance CanReplicateM (Vector a) a Int where
+    replicateM = Vector.replicateM
 
 instance CanFind (Vector a) a where
-    find = V.find
+    find = Vector.find
     
 instance (Monoid m) => CanConcat (Vector m) m where
     concat = Foldable.fold
 
 instance CanPartition (Vector a) a where
-    partition = V.partition
+    partition = Vector.partition
+
+instance CanCons (Vector a) a where
+    cons = Vector.cons
+
+instance CanUncons (Vector a) a where
+    uncons v = if null v then Nothing else Just (Vector.unsafeHead v, Vector.unsafeTail v)
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.4
+version:             0.5.0
 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
@@ -20,11 +20,13 @@
                        ClassyPrelude.Text
                        ClassyPrelude.LText
                        ClassyPrelude.Map
+                       ClassyPrelude.Maybe
                        ClassyPrelude.Set
                        ClassyPrelude.FilePath
                        ClassyPrelude.Vector
                        ClassyPrelude.HashMap
                        ClassyPrelude.HashSet
+                       ClassyPrelude.Char
   build-depends:       base                          >= 4          && < 5
                      , basic-prelude                 >= 0.3.2      && < 0.4
                      , system-filepath               >= 0.4        && < 0.5
diff --git a/test/main.hs b/test/main.hs
--- a/test/main.hs
+++ b/test/main.hs
@@ -46,9 +46,9 @@
             , Eq b
             , Show b
             , Arbitrary b
-            , CanMapFunc a b i j
-            , CanMapFunc a c i k
-            , CanMapFunc b c j k
+            , CanMap a b i j
+            , CanMap a c i k
+            , CanMap b c j k
             )
          => a
          -> (i -> j)
@@ -69,8 +69,8 @@
             , Eq b
             , Show b
             , Arbitrary b
-            , CanMapFunc a b i j
-            , CanConcatMapFunc a b i js
+            , CanMap a b i j
+            , CanConcatMap a b i js
             )
          => a
          -> (i -> js)
@@ -83,7 +83,7 @@
                , Show a
                , Arbitrary a
                , Eq a
-               , CanFilterFunc a a i
+               , CanFilter a i
                )
             => a
             -> (i -> Bool)
@@ -96,7 +96,7 @@
                 , Show a
                 , Arbitrary a
                 , Eq a
-                , CanFilterMFunc a i
+                , CanFilterM a i
                 )
              => a
              -> (i -> Bool)
@@ -137,7 +137,7 @@
              , Arbitrary a
              , CanPack a i
              , Eq i
-             , CanMapMFunc a co i i
+             , CanMapM a co i i
              , CanPack co i
              , Eq co
              )
@@ -155,7 +155,7 @@
               , Arbitrary a
               , CanPack a i
               , Eq i
-              , CanMapM_Func a i
+              , CanMapM_ a i
               )
            => a -> Spec
 mapM_Props dummy = do
@@ -224,8 +224,8 @@
 utf8Props :: ( Eq t
              , Show t
              , Arbitrary t
-             , CanEncodeUtf8Func t b
-             , CanDecodeUtf8Func b t
+             , CanEncodeUtf8 t b
+             , CanDecodeUtf8 b t
              ) => t -> Spec
 utf8Props dummy = do
     prop "decodeUtf8 . encodeUtf8 == id" $ \t ->
