Following the dfeuer lead (and using the new name Daniel Wagner for this function),
import Data.Bool (bool) -- FT -- bool :: a -> a -> Bool -> a ensure :: (a -> Bool) -> a -> Maybe a ensure px = bool (const Nothing) Just (px) x ensure p = join (bool (const Nothing) Just . p) = bool (const Nothing) Just =<< p ensure = (bool (const Nothing) Just =<<)
join is a monadic function join :: Monad m => m (ma) -> ma , but for functions it is simple
join kx = kxx (k =<< f) x = k (fx) x
join taken to replace W combinator in text code.
You only wanted it to be potential-free with respect to the value argument, but it easily transformed the equation with join further (readability of the result is another problem), since
= join ((bool (const Nothing) Just .) p) = (join . (bool (const Nothing) Just .)) p
Really,
source share