diff --git a/CHANGES.txt b/CHANGES.txt
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,8 @@
 Changelog for Extra
 
+1.6.8, released 2018-05-24
+    Add notNull
+    Add listDirectories
 1.6.7, released 2018-05-23
     #35, add fold1M and fold1M_
     #34, lots of documentation typos
diff --git a/extra.cabal b/extra.cabal
--- a/extra.cabal
+++ b/extra.cabal
@@ -1,7 +1,7 @@
 cabal-version:      >= 1.18
 build-type:         Simple
 name:               extra
-version:            1.6.7
+version:            1.6.8
 license:            BSD3
 license-file:       LICENSE
 category:           Development
diff --git a/src/Data/List/Extra.hs b/src/Data/List/Extra.hs
--- a/src/Data/List/Extra.hs
+++ b/src/Data/List/Extra.hs
@@ -19,7 +19,7 @@
     wordsBy, linesBy,
     breakOn, breakOnEnd, splitOn, split, chunksOf,
     -- * Basics
-    list, uncons, unsnoc, cons, snoc, drop1, mconcatMap,
+    notNull, list, uncons, unsnoc, cons, snoc, drop1, mconcatMap,
     -- * List operations
     groupSort, groupSortOn, groupSortBy,
     nubOrd, nubOrdBy, nubOrdOn,
@@ -95,6 +95,14 @@
 allSame [] = True
 allSame (x:xs) = all (x ==) xs
 
+
+-- | A composition of 'not' and 'null'.
+--
+-- > notNull []  == False
+-- > notNull [1] == True
+-- > \xs -> notNull xs == not (null xs)
+notNull :: [a] -> Bool
+notNull = not . null
 
 -- | Non-recursive transform over a list, like 'maybe'.
 --
diff --git a/src/Extra.hs b/src/Extra.hs
--- a/src/Extra.hs
+++ b/src/Extra.hs
@@ -23,7 +23,7 @@
     modifyIORef', writeIORef', atomicModifyIORef', atomicWriteIORef, atomicWriteIORef',
     -- * Data.List.Extra
     -- | Extra functions available in @"Data.List.Extra"@.
-    lower, upper, trim, trimStart, trimEnd, word1, line1, escapeHTML, escapeJSON, unescapeHTML, unescapeJSON, dropEnd, takeEnd, splitAtEnd, breakEnd, spanEnd, dropWhileEnd, dropWhileEnd', takeWhileEnd, stripSuffix, stripInfix, stripInfixEnd, dropPrefix, dropSuffix, wordsBy, linesBy, breakOn, breakOnEnd, splitOn, split, chunksOf, list, uncons, unsnoc, cons, snoc, drop1, mconcatMap, groupSort, groupSortOn, groupSortBy, nubOrd, nubOrdBy, nubOrdOn, nubOn, groupOn, sortOn, nubSort, nubSortBy, nubSortOn, maximumOn, minimumOn, disjoint, allSame, anySame, repeatedly, for, firstJust, concatUnzip, concatUnzip3, zipFrom, zipWithFrom, replace, merge, mergeBy,
+    lower, upper, trim, trimStart, trimEnd, word1, line1, escapeHTML, escapeJSON, unescapeHTML, unescapeJSON, dropEnd, takeEnd, splitAtEnd, breakEnd, spanEnd, dropWhileEnd, dropWhileEnd', takeWhileEnd, stripSuffix, stripInfix, stripInfixEnd, dropPrefix, dropSuffix, wordsBy, linesBy, breakOn, breakOnEnd, splitOn, split, chunksOf, notNull, list, uncons, unsnoc, cons, snoc, drop1, mconcatMap, groupSort, groupSortOn, groupSortBy, nubOrd, nubOrdBy, nubOrdOn, nubOn, groupOn, sortOn, nubSort, nubSortBy, nubSortOn, maximumOn, minimumOn, disjoint, allSame, anySame, repeatedly, for, firstJust, concatUnzip, concatUnzip3, zipFrom, zipWithFrom, replace, merge, mergeBy,
     -- * Data.Tuple.Extra
     -- | Extra functions available in @"Data.Tuple.Extra"@.
     first, second, (***), (&&&), dupe, both, fst3, snd3, thd3,
@@ -38,7 +38,7 @@
     showDP, intToDouble, intToFloat, floatToDouble, doubleToFloat,
     -- * System.Directory.Extra
     -- | Extra functions available in @"System.Directory.Extra"@.
-    withCurrentDirectory, createDirectoryPrivate, listContents, listFiles, listFilesInside, listFilesRecursive,
+    withCurrentDirectory, createDirectoryPrivate, listContents, listDirectories, listFiles, listFilesInside, listFilesRecursive,
     -- * System.Environment.Extra
     -- | Extra functions available in @"System.Environment.Extra"@.
     getExecutablePath, lookupEnv,
diff --git a/src/System/Directory/Extra.hs b/src/System/Directory/Extra.hs
--- a/src/System/Directory/Extra.hs
+++ b/src/System/Directory/Extra.hs
@@ -17,7 +17,7 @@
     withCurrentDirectory,
 #endif
     createDirectoryPrivate,
-    listContents, listFiles, listFilesInside, listFilesRecursive
+    listContents, listDirectories, listFiles, listFilesInside, listFilesRecursive
     ) where
 
 import System.Directory
@@ -58,6 +58,15 @@
 listContents dir = do
     xs <- getDirectoryContents dir
     return $ sort [dir </> x | x <- xs, not $ all (== '.') x]
+
+
+-- | Like 'listContents', but only returns the directories in a directory, not the files.
+--   Each directory will be prefixed by the query directory.
+--
+-- > listTest listDirectories ["bar.txt","foo/baz.txt","zoo"] ["foo"]
+listDirectories :: FilePath -> IO [FilePath]
+listDirectories dir = filterM doesDirectoryExist =<< listContents dir
+
 
 -- | Like 'listContents', but only returns the files in a directory, not other directories.
 --   Each file will be prefixed by the query directory.
diff --git a/test/TestGen.hs b/test/TestGen.hs
--- a/test/TestGen.hs
+++ b/test/TestGen.hs
@@ -82,6 +82,9 @@
     testGen "allSame []      == True" $ allSame []      == True
     testGen "allSame (1:1:2:undefined) == False" $ allSame (1:1:2:undefined) == False
     testGen "\\xs -> allSame xs == (length (nub xs) <= 1)" $ \xs -> allSame xs == (length (nub xs) <= 1)
+    testGen "notNull []  == False" $ notNull []  == False
+    testGen "notNull [1] == True" $ notNull [1] == True
+    testGen "\\xs -> notNull xs == not (null xs)" $ \xs -> notNull xs == not (null xs)
     testGen "list 1 (\\v _ -> v - 2) [5,6,7] == 3" $ list 1 (\v _ -> v - 2) [5,6,7] == 3
     testGen "list 1 (\\v _ -> v - 2) []      == 1" $ list 1 (\v _ -> v - 2) []      == 1
     testGen "\\nil cons xs -> maybe nil (uncurry cons) (uncons xs) == list nil cons xs" $ \nil cons xs -> maybe nil (uncurry cons) (uncons xs) == list nil cons xs
@@ -236,6 +239,7 @@
     let touch = mapM_ $ \x -> createDirectoryIfMissing True (takeDirectory x) >> writeFile x ""
     let listTest op as bs = withTempDir $ \dir -> do touch $ map (dir </>) as; res <- op dir; return $ map (drop (length dir + 1)) res == bs
     testGen "listTest listContents [\"bar.txt\",\"foo/baz.txt\",\"zoo\"] [\"bar.txt\",\"foo\",\"zoo\"]" $ listTest listContents ["bar.txt","foo/baz.txt","zoo"] ["bar.txt","foo","zoo"]
+    testGen "listTest listDirectories [\"bar.txt\",\"foo/baz.txt\",\"zoo\"] [\"foo\"]" $ listTest listDirectories ["bar.txt","foo/baz.txt","zoo"] ["foo"]
     testGen "listTest listFiles [\"bar.txt\",\"foo/baz.txt\",\"zoo\"] [\"bar.txt\",\"zoo\"]" $ listTest listFiles ["bar.txt","foo/baz.txt","zoo"] ["bar.txt","zoo"]
     testGen "listTest listFilesRecursive [\"bar.txt\",\"zoo\",\"foo\" </> \"baz.txt\"] [\"bar.txt\",\"zoo\",\"foo\" </> \"baz.txt\"]" $ listTest listFilesRecursive ["bar.txt","zoo","foo" </> "baz.txt"] ["bar.txt","zoo","foo" </> "baz.txt"]
     testGen "listTest (listFilesInside $ return . not . isPrefixOf \".\" . takeFileName)    [\"bar.txt\",\"foo\" </> \"baz.txt\",\".foo\" </> \"baz2.txt\", \"zoo\"] [\"bar.txt\",\"zoo\",\"foo\" </> \"baz.txt\"]" $ listTest (listFilesInside $ return . not . isPrefixOf "." . takeFileName)    ["bar.txt","foo" </> "baz.txt",".foo" </> "baz2.txt", "zoo"] ["bar.txt","zoo","foo" </> "baz.txt"]
