module Util where import Control.Monad import System.Exit fixpoint :: Eq a => (a -> a) -> a -> a fixpoint f initVal = let values = iterate f initVal pairs = zip values (tail values) in fst . head $ dropWhile (uncurry (/=)) pairs tryEither :: Either String a -> IO a tryEither (Left err) = die err tryEither (Right x) = return x tryEither' :: Show e => Either e a -> IO a tryEither' (Left err) = die (show err) tryEither' (Right x) = return x fromRight :: Either a b -> b fromRight (Right x) = x fromRight (Left _) = error "fromRight on Left" isRight :: Either a b -> Bool isRight (Right _) = True isRight (Left _) = False while :: Monad m => a -> (a -> m (Maybe a)) -> m () while val f = f val >>= \case Nothing -> return () Just val' -> while val' f whenM :: Monad m => m Bool -> m a -> m () whenM b a = b >>= \b' -> if b' then void a else return () ifM :: Monad m => m Bool -> m a -> m a -> m a ifM b t e = b >>= \b' -> if b' then t else e splitOn :: Eq a => a -> [a] -> [[a]] splitOn _ [] = [[]] splitOn spl (x:xs) | x == spl = [] : splitOn spl xs | otherwise = let (r : rs) = splitOn spl xs in (x:r) : rs