diff --git a/CHANGES b/CHANGES
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,15 @@
+* 0.2.3 (12 January 2016)
+
+  - New function 'divvy' (with associated tests) from Tim Washington.
+
+* 0.2.2r2 (7 Jan 2016)
+
+  - allow base-4.9
+
+* 0.2.2r1 (12 Dec 2014)
+
+  - allow base-4.8
+
 * 0.2.2 (14 April 2013)
 
   - Add 'dropInnerBlanks' combinator for dropping blank chunks between
diff --git a/split.cabal b/split.cabal
--- a/split.cabal
+++ b/split.cabal
@@ -1,5 +1,5 @@
 Name:                split
-Version:             0.2.2
+Version:             0.2.3
 Stability:           stable
 
 Description:         A collection of various methods for splitting
@@ -31,11 +31,11 @@
 Copyright:           (c) Brent Yorgey, Louis Wasserman 2008-2012
 Extra-source-files:  README, test/Properties.hs, CHANGES
 Author:              Brent Yorgey
-Maintainer:          byorgey@cis.upenn.edu
+Maintainer:          byorgey@gmail.com
 Category:            List
 Build-type:          Simple
 Cabal-Version:       >= 1.10
-Tested-with:         GHC ==7.0.4, GHC ==7.2.1, GHC ==7.4.*, GHC ==7.6.1
+Tested-with:         GHC ==7.0.4, GHC ==7.2.1, GHC ==7.4.*, GHC ==7.6.1, GHC ==7.8.3, GHC==7.10.3
 Bug-reports:         http://hub.darcs.net/byorgey/split/issues
 
 Test-suite split-tests
@@ -51,7 +51,7 @@
 
 Library
   ghc-options:       -Wall
-  build-depends:     base <4.8
+  build-depends:     base <4.10
   exposed-modules:   Data.List.Split, Data.List.Split.Internals
   default-language:  Haskell2010
   Hs-source-dirs:    src
diff --git a/src/Data/List/Split.hs b/src/Data/List/Split.hs
--- a/src/Data/List/Split.hs
+++ b/src/Data/List/Split.hs
@@ -44,6 +44,7 @@
                        , splitPlaces
                        , splitPlacesBlanks
                        , chop
+                       , divvy
 
                        -- * Splitting combinators
                        -- $comb
diff --git a/src/Data/List/Split/Internals.hs b/src/Data/List/Split/Internals.hs
--- a/src/Data/List/Split/Internals.hs
+++ b/src/Data/List/Split/Internals.hs
@@ -582,3 +582,33 @@
 chop _ [] = []
 chop f as = b : chop f as'
   where (b, as') = f as
+
+-- | Divides up an input list into a set of sublists, according to 'n' and 'm'
+--   input specifications you provide. Each sublist will have 'n' items, and the
+--   start of each sublist will be offset by 'm' items from the previous one.
+--
+-- > divvy 5 5 [1..20] == [[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[16,17,18,19,20]]
+--
+--   In the case where a source list's trailing elements do no fill an entire
+--   sublist, those trailing elements will be dropped.
+--
+-- > divvy 5 2 [1..10] == [[1,2,3,4,5],[3,4,5,6,7],[5,6,7,8,9]]
+--
+--   As an example, you can generate a moving average over a list of prices:
+-- 
+-- > type Prices = [Float]
+-- > type AveragePrices = [Float]
+-- > 
+-- > average :: [Float] -> Float
+-- > average xs = sum xs / (fromIntegral $ length xs)
+-- > 
+-- > simpleMovingAverage :: Prices -> AveragePrices
+-- > simpleMovingAverage priceList =
+-- >   map average divvyedPrices
+-- >     where divvyedPrices = divvy 20 1 priceList
+
+divvy :: Int -> Int -> [a] -> [[a]]
+divvy _ _ [] = []
+divvy n m lst = filter (\ws -> (n == length ws)) choppedl
+  where choppedl = chop (\xs -> (take n xs , drop m xs)) lst
+
diff --git a/test/Properties.hs b/test/Properties.hs
--- a/test/Properties.hs
+++ b/test/Properties.hs
@@ -120,6 +120,11 @@
             , ("linesBy/lines",                 qc prop_linesBy_lines)
             , ("chop/group",                    qc prop_chop_group)
             , ("chop/words",                    qc prop_chop_words)
+            , ("divvy/evenly",                  qc prop_divvy_evenly)
+            , ("divvy/discard_remainder",  qc prop_divvy_discard_remainder)
+            , ("divvy/outputlists_allsame_length", qc prop_divvy_outputlists_allsame_length)
+            , ("divvy/output_are_sublists", qc prop_divvy_output_are_sublists)
+            , ("divvy/heads", qc prop_divvy_heads)
             ]
 
 prop_default_id :: [Elt] -> Bool
@@ -357,3 +362,37 @@
 prop_chop_words :: [EltWS] -> Bool
 prop_chop_words s = words s' == (filter (not . null) . chop (span (not . isSpace) . dropWhile isSpace) $ s')
   where s' = map unEltWS s
+
+prop_divvy_evenly :: [Elt] -> Positive Int -> Property
+prop_divvy_evenly elems (Positive n) = (length elems `mod` n == 0) ==> concat (divvy n n elems) == elems
+
+prop_divvy_discard_remainder :: [Elt] -> Positive Int -> Bool
+prop_divvy_discard_remainder elems (Positive n) =
+  concat (divvy n n elems) == (reverse . drop (length elems `mod` n) . reverse $ elems)
+
+prop_divvy_outputlists_allsame_length :: [Elt] -> Positive Int -> Positive Int -> Bool
+prop_divvy_outputlists_allsame_length elems (Positive n) (Positive m) = allSame xs
+  where
+    allSame :: [Int] -> Bool
+    allSame [] = True
+    allSame zs = and $ map (== head zs) (tail zs)
+    xs = map length (divvy n m elems)
+
+prop_divvy_output_are_sublists :: [Elt] -> Positive Int -> Positive Int -> Bool
+prop_divvy_output_are_sublists elems (Positive n) (Positive m) = and $ map (\x -> isInfixOf x elems) xs
+  where xs = divvy n m elems
+
+takeEvery :: Int -> [a] -> [a]
+takeEvery _ [] = []
+takeEvery n lst = (map head . chunksOf n) $ lst
+
+initNth :: Int -> [a] -> [a]
+initNth _ [] = []
+initNth n lst = (reverse . drop n . reverse) $ lst
+
+prop_divvy_heads :: [Elt] -> Positive Int -> Positive Int -> Bool
+prop_divvy_heads [] _ _ = True
+prop_divvy_heads elems (Positive n) (Positive m) = hds1 == hds2
+  where hds1 = takeEvery m (initNth (n - 1) elems)
+        hds2 = map head $ divvy n m elems
+
