aboutsummaryrefslogtreecommitdiff
path: root/src/Util.hs
blob: 98943f087b386aab74cc38dab8a93f5fb6d2595e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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