[Haskell-cafe] golf,
predicate check function for MonadPlus (was Re: How to read safely?)
Dan Doel
dan.doel at gmail.com
Mon Jul 6 21:49:46 EDT 2009
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
More information about the Haskell-Cafe
mailing list