import Control.Monad
import Control.Monad.Identity
import Control.Monad.Trans.Maybe
import System.Environment
tryR :: Monad m => ([a] -> MaybeT m [a]) -> ([a] -> m [a])
tryR f x = do
m <- runMaybeT (f x)
case m of
Just t -> return t
Nothing -> return x
check :: MonadPlus m => Int -> m Int
check x = if x `mod` 2 == 0 then return (x `div` 2) else mzero
foo :: MonadPlus m => [Int] -> m [Int]
foo [] = return []
foo (x:xs) = liftM2 (:) (check x) (tryR foo xs)
runFoo :: [Int] -> [Int]
runFoo x = runIdentity $ tryR foo x
import Data.Time
bogoBench :: [a] -> IO NominalDiffTime
bogoBench x = do
t₀<-getCurrentTime
last (reverse x) `seq` (fmap (`diffUTCTime`t₀) getCurrentTime)
{-# LANGUAGE TupleSections #-}
timings <- mapM (\n -> (n,) <$> bogoBench (runFoo [2,4..n])) [2,4 .. 50]
import Graphics.Rendering.Chart.Easy
toRenderable . plot
$ line "t" [[(fromIntegral n, realToFrac t) :: (Double, LogValue) | (n,t) <- timings]]