diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,4 +1,7 @@
-# 0.2.0.0
+# 0.1.3.0
+* Added `measure`, a combinator that returns the time span an action takes.
+
+# 0.1.1.0
 * Added `Time.Adjust`, an action that takes a time unit and adds it to the custom start time, if available.
 * Added `Fractional` instances for sub-second time units that treat literals as seconds.
 
diff --git a/lib/Polysemy/Time/Data/TimeUnit.hs b/lib/Polysemy/Time/Data/TimeUnit.hs
--- a/lib/Polysemy/Time/Data/TimeUnit.hs
+++ b/lib/Polysemy/Time/Data/TimeUnit.hs
@@ -32,7 +32,7 @@
   fromNanos :: NanoSeconds -> u
   default fromNanos :: Integral u => NanoSeconds -> u
   fromNanos n =
-    fromIntegral (n `div` (fromIntegral (nanos @u)))
+    fromIntegral (n `div` (nanos @u))
 
 -- * Data types used to specify time spans, e.g. for sleeping.
 
diff --git a/lib/Polysemy/Time/Diff.hs b/lib/Polysemy/Time/Diff.hs
--- a/lib/Polysemy/Time/Diff.hs
+++ b/lib/Polysemy/Time/Diff.hs
@@ -6,6 +6,7 @@
 import Polysemy.Time.Data.TimeUnit (TimeUnit, convert)
 
 diff ::
+  ∀ dt u i1 i2 .
   TimeUnit u =>
   Torsor dt u =>
   Instant i1 dt =>
diff --git a/lib/Polysemy/Time/Ghc.hs b/lib/Polysemy/Time/Ghc.hs
--- a/lib/Polysemy/Time/Ghc.hs
+++ b/lib/Polysemy/Time/Ghc.hs
@@ -7,7 +7,7 @@
 import Polysemy.Time.At (interpretTimeAt)
 import qualified Polysemy.Time.Data.Time as Time
 import Polysemy.Time.Data.Time (Time)
-import Polysemy.Time.Data.TimeUnit (MicroSeconds(MicroSeconds), convert)
+import Polysemy.Time.Data.TimeUnit (MicroSeconds (MicroSeconds), convert)
 import Polysemy.Time.Orphans ()
 
 -- |Convenience alias for 'Data.Time'.
diff --git a/lib/Polysemy/Time/Measure.hs b/lib/Polysemy/Time/Measure.hs
new file mode 100644
--- /dev/null
+++ b/lib/Polysemy/Time/Measure.hs
@@ -0,0 +1,28 @@
+module Polysemy.Time.Measure where
+
+import Torsor (Torsor)
+
+import Polysemy.Time.Class.Instant (Instant)
+import qualified Polysemy.Time.Data.Time as Time
+import Polysemy.Time.Data.Time (Time)
+import Polysemy.Time.Data.TimeUnit (TimeUnit)
+import Polysemy.Time.Diff (diff)
+
+-- |Run the action @ma@ and measure the time it takes.
+--
+-- The type of the difference depends on the functional dependencies of the classes 'Instant' and 'Torsor', where the
+-- input to the former is taken from the type @t@ of 'Time' which is instantiated by an interpreter.
+measure ::
+  ∀ dt t d u r a .
+  TimeUnit u =>
+  Torsor dt u =>
+  Instant t dt =>
+  Member (Time t d) r =>
+  Sem r a ->
+  Sem r (u, a)
+measure ma = do
+  !start <- Time.now @t @d
+  a <- ma
+  !end <- Time.now @t @d
+  pure (diff end start, a)
+{-# inline measure #-}
diff --git a/lib/Polysemy/Time/Prelude.hs b/lib/Polysemy/Time/Prelude.hs
--- a/lib/Polysemy/Time/Prelude.hs
+++ b/lib/Polysemy/Time/Prelude.hs
@@ -300,7 +300,6 @@
 {-# inline mneToList #-}
 
 safeDiv ::
-  Eq a =>
   Real a =>
   Integral a =>
   a ->
@@ -313,7 +312,6 @@
 {-# inline safeDiv #-}
 
 divOr0 ::
-  Eq a =>
   Real a =>
   Integral a =>
   a ->
diff --git a/polysemy-time.cabal b/polysemy-time.cabal
--- a/polysemy-time.cabal
+++ b/polysemy-time.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           polysemy-time
-version:        0.1.2.4
+version:        0.1.3.0
 synopsis:       Polysemy Effect for Time
 description:    Please see the readme on Github at <https://github.com/tek/polysemy-time>
 category:       Time
@@ -30,6 +30,7 @@
       Polysemy.Time.Debug
       Polysemy.Time.Diff
       Polysemy.Time.Ghc
+      Polysemy.Time.Measure
       Polysemy.Time.Orphans
       Polysemy.Time.Prelude
       Polysemy.Time.Sleep
@@ -121,8 +122,9 @@
   type: exitcode-stdio-1.0
   main-is: Main.hs
   other-modules:
-      Polysemy.Time.GhcTimeTest
-      Polysemy.Time.TimeUnitTest
+      Polysemy.Time.Test.GhcTimeTest
+      Polysemy.Time.Test.MeasureTest
+      Polysemy.Time.Test.TimeUnitTest
       Paths_polysemy_time
   hs-source-dirs:
       test
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -1,8 +1,9 @@
 module Main where
 
 import Polysemy.Test (unitTest)
-import Polysemy.Time.GhcTimeTest (test_ghcTime, test_ghcTimeAt)
-import Polysemy.Time.TimeUnitTest (test_fractional)
+import Polysemy.Time.Test.GhcTimeTest (test_ghcTime, test_ghcTimeAt)
+import Polysemy.Time.Test.MeasureTest (test_measure)
+import Polysemy.Time.Test.TimeUnitTest (test_fractional)
 import Test.Tasty (TestTree, defaultMain, testGroup)
 
 tests :: TestTree
@@ -10,7 +11,8 @@
   testGroup "unit" [
     unitTest "ghc time" test_ghcTime,
     unitTest "ghc time at instant" test_ghcTimeAt,
-    unitTest "convert Fractional to TimeUnit" test_fractional
+    unitTest "convert Fractional to TimeUnit" test_fractional,
+    unitTest "measure time an action takes" test_measure
   ]
 
 main :: IO ()
diff --git a/test/Polysemy/Time/GhcTimeTest.hs b/test/Polysemy/Time/GhcTimeTest.hs
deleted file mode 100644
--- a/test/Polysemy/Time/GhcTimeTest.hs
+++ /dev/null
@@ -1,39 +0,0 @@
-module Polysemy.Time.GhcTimeTest where
-
-import Data.Time (Day, UTCTime)
-
-import Polysemy.Test (UnitTest, assert, runTestAuto, (===))
-import Polysemy.Test.Data.Hedgehog (Hedgehog)
-import Polysemy.Time (Time, mkDatetime, year)
-import qualified Polysemy.Time.Data.Time as Time
-import Polysemy.Time.Data.TimeUnit (Days(Days), Seconds(Seconds))
-import Polysemy.Time.Ghc (interpretTimeGhc, interpretTimeGhcAt)
-
-prog ::
-  Ord t =>
-  Members [Time t d, Hedgehog IO] r =>
-  Sem r ()
-prog = do
-  time1 <- Time.now
-  time2 <- Time.now
-  assert (time1 < time2)
-
-test_ghcTime :: UnitTest
-test_ghcTime =
-  runTestAuto do
-    interpretTimeGhc prog
-
-testTime :: UTCTime
-testTime =
-  mkDatetime 1845 12 31 23 59 59
-
-test_ghcTimeAt :: UnitTest
-test_ghcTimeAt =
-  runTestAuto do
-    interpretTimeGhcAt testTime do
-      Time.sleep @UTCTime @Day (Seconds 1)
-      time <- Time.now
-      1846 === year time
-      Time.adjust (Days 366)
-      time1 <- Time.now
-      1847 === year time1
diff --git a/test/Polysemy/Time/Test/GhcTimeTest.hs b/test/Polysemy/Time/Test/GhcTimeTest.hs
new file mode 100644
--- /dev/null
+++ b/test/Polysemy/Time/Test/GhcTimeTest.hs
@@ -0,0 +1,40 @@
+module Polysemy.Time.Test.GhcTimeTest where
+
+import Data.Time (Day, UTCTime)
+import Polysemy.Test (UnitTest, assert, runTestAuto, (===))
+import Polysemy.Test.Data.Hedgehog (Hedgehog)
+
+import Polysemy.Time.Calendar (mkDatetime, year)
+import qualified Polysemy.Time.Data.Time as Time
+import Polysemy.Time.Data.Time (Time)
+import Polysemy.Time.Data.TimeUnit (Days (Days), Seconds (Seconds))
+import Polysemy.Time.Ghc (interpretTimeGhc, interpretTimeGhcAt)
+
+prog ::
+  Ord t =>
+  Members [Time t d, Hedgehog IO] r =>
+  Sem r ()
+prog = do
+  time1 <- Time.now
+  time2 <- Time.now
+  assert (time1 < time2)
+
+test_ghcTime :: UnitTest
+test_ghcTime =
+  runTestAuto do
+    interpretTimeGhc prog
+
+testTime :: UTCTime
+testTime =
+  mkDatetime 1845 12 31 23 59 59
+
+test_ghcTimeAt :: UnitTest
+test_ghcTimeAt =
+  runTestAuto do
+    interpretTimeGhcAt testTime do
+      Time.sleep @UTCTime @Day (Seconds 1)
+      time <- Time.now
+      1846 === year time
+      Time.adjust (Days 366)
+      time1 <- Time.now
+      1847 === year time1
diff --git a/test/Polysemy/Time/Test/MeasureTest.hs b/test/Polysemy/Time/Test/MeasureTest.hs
new file mode 100644
--- /dev/null
+++ b/test/Polysemy/Time/Test/MeasureTest.hs
@@ -0,0 +1,21 @@
+module Polysemy.Time.Test.MeasureTest where
+
+import Polysemy.Test (UnitTest, assert, runTestAuto)
+
+import qualified Polysemy.Time.Data.Time as Time
+import Polysemy.Time.Data.TimeUnit (MilliSeconds (MilliSeconds), convert)
+import Polysemy.Time.Ghc (interpretTimeGhc)
+import Polysemy.Time.Measure (measure)
+
+test_measure :: UnitTest
+test_measure =
+  runTestAuto do
+    interpretTimeGhc do
+      (t1, t2) <- measure do
+        Time.sleep (MilliSeconds 100)
+        fst <$> measure (Time.sleep (MilliSeconds 100))
+      assert (t2 > convert (MilliSeconds 100))
+      assert (t1 > convert (MilliSeconds 200))
+      assert (t2 < t1)
+      assert (t2 < convert (MilliSeconds 200))
+
diff --git a/test/Polysemy/Time/Test/TimeUnitTest.hs b/test/Polysemy/Time/Test/TimeUnitTest.hs
new file mode 100644
--- /dev/null
+++ b/test/Polysemy/Time/Test/TimeUnitTest.hs
@@ -0,0 +1,12 @@
+module Polysemy.Time.Test.TimeUnitTest where
+
+import Polysemy.Test (UnitTest, runTestAuto, (===))
+
+import Polysemy.Time.Data.TimeUnit (MicroSeconds (MicroSeconds), MilliSeconds (MilliSeconds))
+
+test_fractional :: UnitTest
+test_fractional =
+  runTestAuto do
+    MilliSeconds 50 === 0.05
+    MicroSeconds 200 === 0.0002
+    MilliSeconds 50 === (MilliSeconds 100 / MilliSeconds 2)
diff --git a/test/Polysemy/Time/TimeUnitTest.hs b/test/Polysemy/Time/TimeUnitTest.hs
deleted file mode 100644
--- a/test/Polysemy/Time/TimeUnitTest.hs
+++ /dev/null
@@ -1,12 +0,0 @@
-module Polysemy.Time.TimeUnitTest where
-
-import Polysemy.Test (UnitTest, runTestAuto, (===))
-
-import Polysemy.Time.Data.TimeUnit (MicroSeconds(MicroSeconds), MilliSeconds(MilliSeconds))
-
-test_fractional :: UnitTest
-test_fractional =
-  runTestAuto do
-    MilliSeconds 50 === 0.05
-    MicroSeconds 200 === 0.0002
-    MilliSeconds 50 === (MilliSeconds 100 / MilliSeconds 2)
