
On Thursday 02 July 2009 6:36:09 am Jon Fairbairn wrote:
check :: (MonadPlus m) => (a -> Bool) -> a -> m a check p a | p a = return a | otherwise = mzero
I tried Hoogling for a function like check, but couldn't find it. Surely there's one in a library somewhere? It looks useful to me. (I'm rather taken by way the "check (all isSpace . snd)" part reads)
Monad.guard comes close but fails to get the cigar; in fact
guard b == check (const b) ()
So check is more general.
I've often noticed the need for a similar function in conjunction with unfoldr: -- This is overly general for unfoldr, but it lines up with check stopAt :: (MonadPlus m) => (a -> Bool) -> (a -> b) -> a -> m b stopAt p f x | p x = mzero | otherwise = return (f x) -- stopAt p f x = guard (not $ p x) >> return (f x) -- stopAt p f = liftM2 (>>) (guard . not . p) (return . f) -- etc. Then you can write: unfoldr (stopAt p $ f) where p is a stopping predicate based on the seed, and f unfolds the seed one step. This lets you use the many functions in the standard library that have types like: s -> (a, s) where unfoldr wants them to instead be: s -> Maybe (a, s) However, I don't really like the name stopAt, and have never come up with anything better. And of course: check = flip stopAt id . not -- Dan