module Data.Function.AlmostFix where import Control.Monad -- | Applies the predicate to the input: -- @almostFix (< 5) (+1) 0 = @ almostFix :: (a -> Bool) -> (a -> a) -> a -> a almostFix p f x = if p x then almostFix p f (f x) else x -- | Applies the predicate to the result. almostFix' :: (a -> Bool) -> (a -> a) -> a -> a almostFix' p f x = if p (f x) then almostFix' p f (f x) else x -- | Use a monadic predicate for the control flow. almostFixM :: Monad m => m Bool -> (a -> m a) -> a -> m a almostFixM p f x = do p' <- p if p' then almostFixM p f =<< f x else return x