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]]