summaryrefslogtreecommitdiff
path: root/compiler/utils/Util.lhs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/utils/Util.lhs')
-rw-r--r--compiler/utils/Util.lhs31
1 files changed, 27 insertions, 4 deletions
diff --git a/compiler/utils/Util.lhs b/compiler/utils/Util.lhs
index 90a2077c71..5c82c757aa 100644
--- a/compiler/utils/Util.lhs
+++ b/compiler/utils/Util.lhs
@@ -14,11 +14,11 @@ module Util (
-- * General list processing
zipEqual, zipWithEqual, zipWith3Equal, zipWith4Equal,
- zipLazy, stretchZipWith,
+ zipLazy, stretchZipWith, zipWithAndUnzip,
unzipWith,
- mapFst, mapSnd,
+ mapFst, mapSnd, chkAppend,
mapAndUnzip, mapAndUnzip3, mapAccumL2,
nOfThem, filterOut, partitionWith, splitEithers,
@@ -259,6 +259,13 @@ splitEithers (e : es) = case e of
Left x -> (x:xs, ys)
Right y -> (xs, y:ys)
where (xs,ys) = splitEithers es
+
+chkAppend :: [a] -> [a] -> [a]
+-- Checks for the second arguemnt being empty
+-- Used in situations where that situation is common
+chkAppend xs ys
+ | null ys = xs
+ | otherwise = xs ++ ys
\end{code}
A paranoid @zip@ (and some @zipWith@ friends) that checks the lists
@@ -344,6 +351,14 @@ mapAndUnzip3 f (x:xs)
in
(r1:rs1, r2:rs2, r3:rs3)
+zipWithAndUnzip :: (a -> b -> (c,d)) -> [a] -> [b] -> ([c],[d])
+zipWithAndUnzip f (a:as) (b:bs)
+ = let (r1, r2) = f a b
+ (rs1, rs2) = zipWithAndUnzip f as bs
+ in
+ (r1:rs1, r2:rs2)
+zipWithAndUnzip _ _ _ = ([],[])
+
mapAccumL2 :: (s1 -> s2 -> a -> (s1, s2, b)) -> s1 -> s2 -> [a] -> (s1, s2, [b])
mapAccumL2 f s1 s2 xs = (s1', s2', ys)
where ((s1', s2'), ys) = mapAccumL (\(s1, s2) x -> case f s1 s2 x of
@@ -559,7 +574,15 @@ splitAtList (_:xs) (y:ys) = (y:ys', ys'')
-- drop from the end of a list
dropTail :: Int -> [a] -> [a]
-dropTail n = reverse . drop n . reverse
+-- Specification: dropTail n = reverse . drop n . reverse
+-- Better implemention due to Joachim Breitner
+-- http://www.joachim-breitner.de/blog/archives/600-On-taking-the-last-n-elements-of-a-list.html
+dropTail n xs
+ = go (drop n xs) xs
+ where
+ go (_:ys) (x:xs) = x : go ys xs
+ go _ _ = [] -- Stop when ys runs out
+ -- It'll always run out before xs does
snocView :: [a] -> Maybe ([a],a)
-- Split off the last element
@@ -1088,7 +1111,7 @@ charToC w =
hashString :: String -> Int32
hashString = foldl' f golden
where f m c = fromIntegral (ord c) * magic + hashInt32 m
- magic = 0xdeadbeef
+ magic = fromIntegral (0xdeadbeef :: Word32)
golden :: Int32
golden = 1013904242 -- = round ((sqrt 5 - 1) * 2^32) :: Int32