diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
 # Revision history for schedule
 
+## 0.3.0.0 -- 2020-04-03
+
+* Update to GHC 8.8.3, remove some redundant imports.
+* Tweak Control.Clock.IO API to be more flexible
+
 ## 0.2.0.0 -- 2019-12-20
 
 * Minor API and documentation tweaks.
diff --git a/schedule.cabal b/schedule.cabal
--- a/schedule.cabal
+++ b/schedule.cabal
@@ -1,6 +1,6 @@
 Cabal-Version:       2.4
 Name:                schedule
-Version:             0.2.0.0
+Version:             0.3.0.0
 Synopsis:            Pure deterministic scheduled computations
 Description:
   Schedule computations to run later, in a pure and deterministic way.
@@ -61,9 +61,9 @@
 License-File:        LICENSE.GPL-3
 Author:              Ximin Luo
 Maintainer:          infinity0@pwned.gg
-Copyright:           2016-2019 Ximin Luo
+Copyright:           2016-2020 Ximin Luo
 Category:            Control, Schedule, Delay, Time, Timeout
-Tested-With:         GHC >= 8.6
+Tested-With:         GHC >= 8.8.3
 Extra-Source-Files:  CHANGELOG.md
 
 Source-Repository head
diff --git a/src/Control/Clock/IO.hs b/src/Control/Clock/IO.hs
--- a/src/Control/Clock/IO.hs
+++ b/src/Control/Clock/IO.hs
@@ -4,10 +4,9 @@
 {-| Implementations of 'Clock' in the 'IO' monad. -}
 module Control.Clock.IO
   ( newClock
-  , newClockPico
-  , newClockMilli
-  , newClock1ms
-  , newClock1s
+  , newClock'
+  , Intv(..)
+  , interval
   , convClock
   , clockWithIO
   , clockTimerIO
@@ -38,25 +37,23 @@
 import           Control.Clock
 
 
--- | Create a new clock ticking at a given interval.
-newClock :: DiffTime -> IO (Clock IO)
-newClock intv = convClock intv <$> T.newClock
-
--- | Create a new clock ticking at a given interval in picoseconds.
-newClockPico :: Integer -> IO (Clock IO)
-newClockPico = newClock . picosecondsToDiffTime
+-- | Create a new clock with the given start tick and interval.
+newClock :: Tick -> DiffTime -> IO (Clock IO)
+newClock start intv = convClock start intv <$> T.newClock
 
--- | Create a new clock ticking at a given interval in milliseconds.
-newClockMilli :: Integer -> IO (Clock IO)
-newClockMilli ms = newClockPico (1000000000 * ms)
+newClock' :: DiffTime -> IO (Clock IO)
+newClock' = newClock 0
 
--- | Create a new clock ticking at 1 millisecond.
-newClock1ms :: IO (Clock IO)
-newClock1ms = newClockMilli 1
+data Intv = Ps | Ns | Us | Ms | S
 
--- | Create a new clock ticking at 1 second.
-newClock1s :: IO (Clock IO)
-newClock1s = newClockMilli 1000
+-- | Convenience method for creating @DiffTime@ for use with @newClock@.
+interval :: Integer -> Intv -> DiffTime
+interval i u = picosecondsToDiffTime $ case u of
+  Ps -> i
+  Ns -> 1000 * i
+  Us -> 1000000 * i
+  Ms -> 1000000000 * i
+  S  -> 1000000000000 * i
 
 -- | Check for a non-negative number.
 checkNonNeg :: (HasCallStack, Num a, Ord a, Show a) => a -> a
@@ -70,13 +67,14 @@
 {-| Convert a "System.Time.Monotonic.Clock" into an abstract 'Clock' for
     scheduled computations, ticking at the given interval.
 -}
-convClock :: DiffTime -> T.Clock -> Clock IO
-convClock intv c =
+convClock :: Tick -> DiffTime -> T.Clock -> Clock IO
+convClock start intv c =
   let r  = diffTimeToPicoseconds $ checkPos intv
+      i  = start * r
       c' = Clock
-        { clockNow   = (`div` r) <$> clockNowPico c
+        { clockNow   = (`div` r) <$> clockNowPico i c
         , clockDelay = \d -> when (d > 0) $ do
-                         remain <- (`rem` r) <$> clockNowPico c
+                         remain <- (`rem` r) <$> clockNowPico i c
                          -- wait a bit past the tick, make sure we've gone over
                          let t = r * fromIntegral d * 16 `div` 15 - remain
                          clockDelayPico t
@@ -85,8 +83,8 @@
         }
   in  c'
 
-clockNowPico :: T.Clock -> IO Integer
-clockNowPico c = diffTimeToPicoseconds <$> T.clockGetTime c
+clockNowPico :: Tick -> T.Clock -> IO Integer
+clockNowPico start c = (start +) . diffTimeToPicoseconds <$> T.clockGetTime c
 
 clockDelayPico :: Integer -> IO ()
 clockDelayPico d = T.delay $ picosecondsToDiffTime $ checkNonNeg d
diff --git a/src/Control/Monad/Schedule.hs b/src/Control/Monad/Schedule.hs
--- a/src/Control/Monad/Schedule.hs
+++ b/src/Control/Monad/Schedule.hs
@@ -20,7 +20,6 @@
 
 -- external
 import           Control.Monad.Extra    (whenMaybe)
-import           Data.Either            (either)
 import           Data.Functor.Identity  (Identity (..))
 import           Data.Maybe             (fromMaybe)
 
diff --git a/src/Data/Rsv/RMMap.hs b/src/Data/Rsv/RMMap.hs
--- a/src/Data/Rsv/RMMap.hs
+++ b/src/Data/Rsv/RMMap.hs
@@ -85,7 +85,7 @@
 checkValidity :: RMMap k a -> Maybe Text
 checkValidity (RMMap handles' content') =
   let res = flip mapMaybe (M.toList content') $ \(k, hh) -> do
-        if any (not . R.checkHandle handles' . fst) hh then Just k else Nothing
+        if not (all (R.checkHandle handles' . fst) hh) then Just k else Nothing
   in  case res of
         [] -> Nothing
         e  -> Just $ pack "some handles were reused in the input"
diff --git a/test/Control/Monad/ScheduleTest.hs b/test/Control/Monad/ScheduleTest.hs
--- a/test/Control/Monad/ScheduleTest.hs
+++ b/test/Control/Monad/ScheduleTest.hs
@@ -55,7 +55,7 @@
   -> RunSched Tick (tm IO)
   -> IO ()
 smoke mkRecv runWithNew runSched = do
-  clock <- newClock1ms
+  clock <- newClock' (interval 1 Ms)
   recv  <- mkRecv clock
   let top = 17
   (r, s) <- runWithNew newSchedule $ do
