module MonadHelp where untilJust :: Monad m => m (Maybe a) -> m a untilJust m = go where go = do mayx <- m maybe go return mayx untilJustCount :: Monad m => m (Maybe a) -> m (a, Int) untilJustCount m = go 0 where go i = do mayx <- m case mayx of Nothing -> go (i+1) Just x -> return (x,i) iterateUntil :: Monad m => (a -> Bool) -> m a -> m a iterateUntil t m = do x <- m if t x then return x else iterateUntil t m iterateWhile :: Monad m => (a -> Bool) -> m a -> m a iterateWhile t = iterateUntil (not . t) unfoldrMID :: (Monad m) => (a -> m (Maybe a)) -> a -> m [a] unfoldrMID f = go where go z = do x <- f z case x of Nothing -> return [z] Just y -> (z :) <$> go y