module Language.Sifflet.Util (
SuccFail(Succ, Fail)
, parsef, parseInt, parseDouble, parseVerbatim
, par
, putCatsLn
, putCatLn
, info
, fake
, stub
, errcat
, errcats
, map2, mapM2
, adjustAList, adjustAListM
, insertLastLast, insertLast
)
where
import Control.Monad()
data SuccFail a = Succ a
| Fail String
deriving (Eq, Read, Show)
instance Functor SuccFail where
fmap f (Succ v) = Succ (f v)
fmap _f (Fail s) = Fail s
instance Applicative SuccFail where
pure = Succ
Succ f <*> Succ v = Succ (f v)
Fail s <*> _ = Fail s
Succ _ <*> Fail s = Fail s
instance Monad SuccFail where
Succ val >>= f = f val
Fail err >>= _f = Fail err
return = Succ
fail = Fail
parsef :: (Read a) => String -> String -> String -> SuccFail a
parsef typeName inputLabel input =
case reads input of
[(value, "")] -> Succ value
[(_, more)] ->
Fail $ inputLabel ++ ": extra characters after " ++
typeName ++ ": " ++ more
_ -> Fail $ inputLabel ++ ": cannot parse as " ++
typeName ++ ": " ++ input
parseInt :: String -> String -> SuccFail Int
parseInt = parsef "integer"
parseDouble :: String -> String -> SuccFail Double
parseDouble = parsef "real number"
parseVerbatim :: String -> String -> SuccFail String
parseVerbatim _label = Succ
par :: String -> [String] -> String
par f xs = "(" ++ unwords (f:xs) ++ ")"
putCatsLn :: [String] -> IO ()
putCatsLn = putStrLn . unwords
putCatLn :: [String] -> IO ()
putCatLn = putStrLn . concat
info :: (Show t) => t -> IO ()
info = print
fake :: String -> IO ()
fake what = putStrLn $ "Faking " ++ what ++ "..."
stub :: String -> IO ()
stub name = putStrLn $ "Stub for " ++ name
errcat :: [String] -> a
errcat = error . concat
errcats :: [String] -> a
errcats = error . unwords
map2 :: (a -> b) -> [[a]] -> [[b]]
map2 f rows =
map (map f) rows
mapM2 :: (Monad m) => (a -> m b) -> [[a]] -> m [[b]]
mapM2 f rows =
mapM (mapM f) rows
insertLastLast :: [[a]] -> a -> [[a]]
insertLastLast xss x = init xss ++ [insertLast (last xss) x]
insertLast :: [a] -> a -> [a]
insertLast xs x = xs ++ [x]
adjustAList :: (Eq k) => k -> (v -> v) -> [(k, v)] -> [(k, v)]
adjustAList key f alist =
map (\ (k, v) -> if k == key then (k, f v) else (k, v))
alist
adjustAListM :: (Eq k, Monad m) =>
k -> (v -> m v) -> [(k, v)] -> m [(k, v)]
adjustAListM key f alist =
mapM (\ (k, v) ->
if k == key
then do { v' <- f v; return (k, v') }
else return (k, v))
alist