module ParkBench.Internal.Benchable
  ( Benchable,
    function,
    action,
    mapIO,
    run,
  )
where

import qualified ParkBench.Internal.Benchable.Internal as Internal
import ParkBench.Internal.Prelude

-- | A benchmarkable thing.
newtype Benchable a
  = Benchable (Word64 -> IO a)

-- | A benchmarkable function. The result is evaluated to weak head normal form.
function :: (a -> b) -> a -> Benchable ()
function :: forall a b. (a -> b) -> a -> Benchable ()
function =
  \a -> b
f a
x -> forall a. (Word64 -> IO a) -> Benchable a
Benchable (forall a b. (a -> b) -> a -> Word64 -> IO ()
Internal.function a -> b
f a
x)
{-# INLINE function #-}

-- | A benchmarkable @IO@ action. The result is evaluated to weak head normal form.
action :: IO a -> Benchable ()
action :: forall a. IO a -> Benchable ()
action =
  \IO a
x -> forall a. (Word64 -> IO a) -> Benchable a
Benchable (forall a. IO a -> Word64 -> IO ()
Internal.action IO a
x)
{-# INLINE action #-}

-- | Map over a benchmarkable thing in @IO@.
mapIO :: (IO a -> IO b) -> Benchable a -> Benchable b
mapIO :: forall a b. (IO a -> IO b) -> Benchable a -> Benchable b
mapIO =
  \IO a -> IO b
f (Benchable Word64 -> IO a
g) ->
    forall a. (Word64 -> IO a) -> Benchable a
Benchable (IO a -> IO b
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> IO a
g)
{-# INLINE mapIO #-}

-- | Run a benchmarkable thing for a number of iterations.
run :: Benchable a -> Word64 -> IO a
run :: forall a. Benchable a -> Word64 -> IO a
run =
  coerce :: forall a b. Coercible a b => a -> b
coerce
{-# INLINE run #-}