-- (c) The University of Glasgow 2006

{-# LANGUAGE CPP #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE MagicHash #-}

{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}

-- | Highly random utility functions
--
module GHC.Utils.Misc (
        -- * Flags dependent on the compiler build
        ghciSupported, debugIsOn,
        isWindowsHost, isDarwinHost,

        -- * Miscellaneous higher-order functions
        applyWhen, nTimes,

        -- * General list processing
        zipEqual, zipWithEqual, zipWith3Equal, zipWith4Equal,
        zipLazy, stretchZipWith, zipWithAndUnzip, zipAndUnzip,

        zipWithLazy, zipWith3Lazy,

        filterByList, filterByLists, partitionByList,

        unzipWith,

        mapFst, mapSnd, chkAppend,
        mapAndUnzip, mapAndUnzip3,
        filterOut, partitionWith,

        dropWhileEndLE, spanEnd, last2, lastMaybe,

        List.foldl1', foldl2, count, countWhile, all2,

        lengthExceeds, lengthIs, lengthIsNot,
        lengthAtLeast, lengthAtMost, lengthLessThan,
        listLengthCmp, atLength,
        equalLength, compareLength, leLength, ltLength,

        isSingleton, only, GHC.Utils.Misc.singleton,
        notNull, snocView,

        isIn, isn'tIn,

        chunkList,

        changeLast,
        mapLastM,

        whenNonEmpty,

        mergeListsBy,
        isSortedBy,

        -- * Tuples
        fstOf3, sndOf3, thdOf3,
        firstM, first3M, secondM,
        fst3, snd3, third3,
        uncurry3,
        liftFst, liftSnd,

        -- * List operations controlled by another list
        takeList, dropList, splitAtList, split,
        dropTail, capitalise,

        -- * Sorting
        sortWith, minWith, nubSort, ordNub,

        -- * Comparisons
        isEqual, eqListBy, eqMaybeBy,
        thenCmp, cmpList,
        removeSpaces,
        (<&&>), (<||>),

        -- * Edit distance
        fuzzyMatch, fuzzyLookup,

        -- * Transitive closures
        transitiveClosure,

        -- * Strictness
        seqList, strictMap, strictZipWith,

        -- * Module names
        looksLikeModuleName,
        looksLikePackageName,

        -- * Argument processing
        getCmd, toCmdArgs, toArgs,

        -- * Integers
        exactLog2,

        -- * Floating point
        readRational,
        readSignificandExponentPair,
        readHexRational,
        readHexSignificandExponentPair,

        -- * IO-ish utilities
        doesDirNameExist,
        getModificationUTCTime,
        modificationTimeIfExists,
        withAtomicRename,

        -- * Filenames and paths
        Suffix,
        splitLongestPrefix,
        escapeSpaces,
        Direction(..), reslash,
        makeRelativeTo,

        -- * Utils for defining Data instances
        abstractConstr, abstractDataType, mkNoRepType,

        -- * Utils for printing C code
        charToC,

        -- * Hashing
        hashString,

        -- * Call stacks
        HasCallStack,
        HasDebugCallStack,

        -- * Utils for flags
        OverridingBool(..),
        overrideWith,
    ) where

#include "HsVersions.h"

import GHC.Prelude

import GHC.Utils.Exception
import GHC.Utils.Panic.Plain

import Data.Data
import qualified Data.List as List
import Data.List.NonEmpty  ( NonEmpty(..) )

import GHC.Exts
import GHC.Stack (HasCallStack)

import Control.Applicative ( liftA2 )
import Control.Monad    ( liftM, guard )
import Control.Monad.IO.Class ( MonadIO, liftIO )
import System.IO.Error as IO ( isDoesNotExistError )
import System.Directory ( doesDirectoryExist, getModificationTime, renameFile )
import System.FilePath

import Data.Char        ( isUpper, isAlphaNum, isSpace, chr, ord, isDigit, toUpper
                        , isHexDigit, digitToInt )
import Data.Int
import Data.Ratio       ( (%) )
import Data.Ord         ( comparing )
import Data.Word
import qualified Data.IntMap as IM
import qualified Data.Set as Set

import Data.Time

#if defined(DEBUG)
import {-# SOURCE #-} GHC.Utils.Outputable ( text )
import {-# SOURCE #-} GHC.Driver.Ppr ( warnPprTrace )
#endif

infixr 9 `thenCmp`

{-
************************************************************************
*                                                                      *
\subsection{Is DEBUG on, are we on Windows, etc?}
*                                                                      *
************************************************************************

These booleans are global constants, set by CPP flags.  They allow us to
recompile a single module (this one) to change whether or not debug output
appears. They sometimes let us avoid even running CPP elsewhere.

It's important that the flags are literal constants (True/False). Then,
with -0, tests of the flags in other modules will simplify to the correct
branch of the conditional, thereby dropping debug code altogether when
the flags are off.
-}

ghciSupported :: Bool
#if defined(HAVE_INTERNAL_INTERPRETER)
ghciSupported :: Bool
ghciSupported = Bool
True
#else
ghciSupported = False
#endif

debugIsOn :: Bool
#if defined(DEBUG)
debugIsOn = True
#else
debugIsOn :: Bool
debugIsOn = Bool
False
#endif

isWindowsHost :: Bool
#if defined(mingw32_HOST_OS)
isWindowsHost = True
#else
isWindowsHost :: Bool
isWindowsHost = Bool
False
#endif

isDarwinHost :: Bool
#if defined(darwin_HOST_OS)
isDarwinHost = True
#else
isDarwinHost :: Bool
isDarwinHost = Bool
False
#endif

{-
************************************************************************
*                                                                      *
\subsection{Miscellaneous higher-order functions}
*                                                                      *
************************************************************************
-}

-- | Apply a function iff some condition is met.
applyWhen :: Bool -> (a -> a) -> a -> a
applyWhen :: forall a. Bool -> (a -> a) -> a -> a
applyWhen Bool
True a -> a
f a
x = a -> a
f a
x
applyWhen Bool
_    a -> a
_ a
x = a
x

-- | Apply a function @n@ times to a given value.
nTimes :: Int -> (a -> a) -> (a -> a)
nTimes :: forall a. Int -> (a -> a) -> a -> a
nTimes Int
0 a -> a
_ = forall a. a -> a
id
nTimes Int
1 a -> a
f = a -> a
f
nTimes Int
n a -> a
f = a -> a
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Int -> (a -> a) -> a -> a
nTimes (Int
nforall a. Num a => a -> a -> a
-Int
1) a -> a
f

fstOf3   :: (a,b,c) -> a
sndOf3   :: (a,b,c) -> b
thdOf3   :: (a,b,c) -> c
fstOf3 :: forall a b c. (a, b, c) -> a
fstOf3      (a
a,b
_,c
_) =  a
a
sndOf3 :: forall a b c. (a, b, c) -> b
sndOf3      (a
_,b
b,c
_) =  b
b
thdOf3 :: forall a b c. (a, b, c) -> c
thdOf3      (a
_,b
_,c
c) =  c
c

fst3 :: (a -> d) -> (a, b, c) -> (d, b, c)
fst3 :: forall a d b c. (a -> d) -> (a, b, c) -> (d, b, c)
fst3 a -> d
f (a
a, b
b, c
c) = (a -> d
f a
a, b
b, c
c)

snd3 :: (b -> d) -> (a, b, c) -> (a, d, c)
snd3 :: forall b d a c. (b -> d) -> (a, b, c) -> (a, d, c)
snd3 b -> d
f (a
a, b
b, c
c) = (a
a, b -> d
f b
b, c
c)

third3 :: (c -> d) -> (a, b, c) -> (a, b, d)
third3 :: forall c d a b. (c -> d) -> (a, b, c) -> (a, b, d)
third3 c -> d
f (a
a, b
b, c
c) = (a
a, b
b, c -> d
f c
c)

uncurry3 :: (a -> b -> c -> d) -> (a, b, c) -> d
uncurry3 :: forall a b c d. (a -> b -> c -> d) -> (a, b, c) -> d
uncurry3 a -> b -> c -> d
f (a
a, b
b, c
c) = a -> b -> c -> d
f a
a b
b c
c

liftFst :: (a -> b) -> (a, c) -> (b, c)
liftFst :: forall a b c. (a -> b) -> (a, c) -> (b, c)
liftFst a -> b
f (a
a,c
c) = (a -> b
f a
a, c
c)

liftSnd :: (a -> b) -> (c, a) -> (c, b)
liftSnd :: forall a b c. (a -> b) -> (c, a) -> (c, b)
liftSnd a -> b
f (c
c,a
a) = (c
c, a -> b
f a
a)

firstM :: Monad m => (a -> m c) -> (a, b) -> m (c, b)
firstM :: forall (m :: * -> *) a c b.
Monad m =>
(a -> m c) -> (a, b) -> m (c, b)
firstM a -> m c
f (a
x, b
y) = forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (\c
x' -> (c
x', b
y)) (a -> m c
f a
x)

first3M :: Monad m => (a -> m d) -> (a, b, c) -> m (d, b, c)
first3M :: forall (m :: * -> *) a d b c.
Monad m =>
(a -> m d) -> (a, b, c) -> m (d, b, c)
first3M a -> m d
f (a
x, b
y, c
z) = forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (\d
x' -> (d
x', b
y, c
z)) (a -> m d
f a
x)

secondM :: Monad m => (b -> m c) -> (a, b) -> m (a, c)
secondM :: forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a, b) -> m (a, c)
secondM b -> m c
f (a
x, b
y) = (a
x,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> b -> m c
f b
y

{-
************************************************************************
*                                                                      *
\subsection[Utils-lists]{General list processing}
*                                                                      *
************************************************************************
-}

filterOut :: (a->Bool) -> [a] -> [a]
-- ^ Like filter, only it reverses the sense of the test
filterOut :: forall a. (a -> Bool) -> [a] -> [a]
filterOut a -> Bool
_ [] = []
filterOut a -> Bool
p (a
x:[a]
xs) | a -> Bool
p a
x       = forall a. (a -> Bool) -> [a] -> [a]
filterOut a -> Bool
p [a]
xs
                   | Bool
otherwise = a
x forall a. a -> [a] -> [a]
: forall a. (a -> Bool) -> [a] -> [a]
filterOut a -> Bool
p [a]
xs

partitionWith :: (a -> Either b c) -> [a] -> ([b], [c])
-- ^ Uses a function to determine which of two output lists an input element should join
partitionWith :: forall a b c. (a -> Either b c) -> [a] -> ([b], [c])
partitionWith a -> Either b c
_ [] = ([],[])
partitionWith a -> Either b c
f (a
x:[a]
xs) = case a -> Either b c
f a
x of
                         Left  b
b -> (b
bforall a. a -> [a] -> [a]
:[b]
bs, [c]
cs)
                         Right c
c -> ([b]
bs, c
cforall a. a -> [a] -> [a]
:[c]
cs)
    where ([b]
bs,[c]
cs) = forall a b c. (a -> Either b c) -> [a] -> ([b], [c])
partitionWith a -> Either b c
f [a]
xs

chkAppend :: [a] -> [a] -> [a]
-- Checks for the second argument being empty
-- Used in situations where that situation is common
chkAppend :: forall a. [a] -> [a] -> [a]
chkAppend [a]
xs [a]
ys
  | forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
ys   = [a]
xs
  | Bool
otherwise = [a]
xs forall a. [a] -> [a] -> [a]
++ [a]
ys

{-
A paranoid @zip@ (and some @zipWith@ friends) that checks the lists
are of equal length.  Alastair Reid thinks this should only happen if
DEBUGging on; hey, why not?
-}

zipEqual        :: String -> [a] -> [b] -> [(a,b)]
zipWithEqual    :: String -> (a->b->c) -> [a]->[b]->[c]
zipWith3Equal   :: String -> (a->b->c->d) -> [a]->[b]->[c]->[d]
zipWith4Equal   :: String -> (a->b->c->d->e) -> [a]->[b]->[c]->[d]->[e]

#if !defined(DEBUG)
zipEqual :: forall a b. String -> [a] -> [b] -> [(a, b)]
zipEqual      String
_ = forall a b. [a] -> [b] -> [(a, b)]
zip
zipWithEqual :: forall a b c. String -> (a -> b -> c) -> [a] -> [b] -> [c]
zipWithEqual  String
_ = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith
zipWith3Equal :: forall a b c d.
String -> (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3Equal String
_ = forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3
zipWith4Equal :: forall a b c d e.
String
-> (a -> b -> c -> d -> e) -> [a] -> [b] -> [c] -> [d] -> [e]
zipWith4Equal String
_ = forall a b c d e.
(a -> b -> c -> d -> e) -> [a] -> [b] -> [c] -> [d] -> [e]
List.zipWith4
#else
zipEqual _   []     []     = []
zipEqual msg (a:as) (b:bs) = (a,b) : zipEqual msg as bs
zipEqual msg _      _      = panic ("zipEqual: unequal lists: "++msg)

zipWithEqual msg z (a:as) (b:bs)=  z a b : zipWithEqual msg z as bs
zipWithEqual _   _ [] []        =  []
zipWithEqual msg _ _ _          =  panic ("zipWithEqual: unequal lists: "++msg)

zipWith3Equal msg z (a:as) (b:bs) (c:cs)
                                =  z a b c : zipWith3Equal msg z as bs cs
zipWith3Equal _   _ [] []  []   =  []
zipWith3Equal msg _ _  _   _    =  panic ("zipWith3Equal: unequal lists: "++msg)

zipWith4Equal msg z (a:as) (b:bs) (c:cs) (d:ds)
                                =  z a b c d : zipWith4Equal msg z as bs cs ds
zipWith4Equal _   _ [] [] [] [] =  []
zipWith4Equal msg _ _  _  _  _  =  panic ("zipWith4Equal: unequal lists: "++msg)
#endif

-- | 'zipLazy' is a kind of 'zip' that is lazy in the second list (observe the ~)
zipLazy :: [a] -> [b] -> [(a,b)]
zipLazy :: forall a b. [a] -> [b] -> [(a, b)]
zipLazy []     [b]
_       = []
zipLazy (a
x:[a]
xs) ~(b
y:[b]
ys) = (a
x,b
y) forall a. a -> [a] -> [a]
: forall a b. [a] -> [b] -> [(a, b)]
zipLazy [a]
xs [b]
ys

-- | 'zipWithLazy' is like 'zipWith' but is lazy in the second list.
-- The length of the output is always the same as the length of the first
-- list.
zipWithLazy :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWithLazy :: forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWithLazy a -> b -> c
_ []     [b]
_       = []
zipWithLazy a -> b -> c
f (a
a:[a]
as) ~(b
b:[b]
bs) = a -> b -> c
f a
a b
b forall a. a -> [a] -> [a]
: forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWithLazy a -> b -> c
f [a]
as [b]
bs

-- | 'zipWith3Lazy' is like 'zipWith3' but is lazy in the second and third lists.
-- The length of the output is always the same as the length of the first
-- list.
zipWith3Lazy :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3Lazy :: forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3Lazy a -> b -> c -> d
_ []     [b]
_       [c]
_       = []
zipWith3Lazy a -> b -> c -> d
f (a
a:[a]
as) ~(b
b:[b]
bs) ~(c
c:[c]
cs) = a -> b -> c -> d
f a
a b
b c
c forall a. a -> [a] -> [a]
: forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3Lazy a -> b -> c -> d
f [a]
as [b]
bs [c]
cs

-- | 'filterByList' takes a list of Bools and a list of some elements and
-- filters out these elements for which the corresponding value in the list of
-- Bools is False. This function does not check whether the lists have equal
-- length.
filterByList :: [Bool] -> [a] -> [a]
filterByList :: forall a. [Bool] -> [a] -> [a]
filterByList (Bool
True:[Bool]
bs)  (a
x:[a]
xs) = a
x forall a. a -> [a] -> [a]
: forall a. [Bool] -> [a] -> [a]
filterByList [Bool]
bs [a]
xs
filterByList (Bool
False:[Bool]
bs) (a
_:[a]
xs) =     forall a. [Bool] -> [a] -> [a]
filterByList [Bool]
bs [a]
xs
filterByList [Bool]
_          [a]
_      = []

-- | 'filterByLists' takes a list of Bools and two lists as input, and
-- outputs a new list consisting of elements from the last two input lists. For
-- each Bool in the list, if it is 'True', then it takes an element from the
-- former list. If it is 'False', it takes an element from the latter list.
-- The elements taken correspond to the index of the Bool in its list.
-- For example:
--
-- @
-- filterByLists [True, False, True, False] \"abcd\" \"wxyz\" = \"axcz\"
-- @
--
-- This function does not check whether the lists have equal length.
filterByLists :: [Bool] -> [a] -> [a] -> [a]
filterByLists :: forall a. [Bool] -> [a] -> [a] -> [a]
filterByLists (Bool
True:[Bool]
bs)  (a
x:[a]
xs) (a
_:[a]
ys) = a
x forall a. a -> [a] -> [a]
: forall a. [Bool] -> [a] -> [a] -> [a]
filterByLists [Bool]
bs [a]
xs [a]
ys
filterByLists (Bool
False:[Bool]
bs) (a
_:[a]
xs) (a
y:[a]
ys) = a
y forall a. a -> [a] -> [a]
: forall a. [Bool] -> [a] -> [a] -> [a]
filterByLists [Bool]
bs [a]
xs [a]
ys
filterByLists [Bool]
_          [a]
_      [a]
_      = []

-- | 'partitionByList' takes a list of Bools and a list of some elements and
-- partitions the list according to the list of Bools. Elements corresponding
-- to 'True' go to the left; elements corresponding to 'False' go to the right.
-- For example, @partitionByList [True, False, True] [1,2,3] == ([1,3], [2])@
-- This function does not check whether the lists have equal
-- length; when one list runs out, the function stops.
partitionByList :: [Bool] -> [a] -> ([a], [a])
partitionByList :: forall a. [Bool] -> [a] -> ([a], [a])
partitionByList = forall {a}. [a] -> [a] -> [Bool] -> [a] -> ([a], [a])
go [] []
  where
    go :: [a] -> [a] -> [Bool] -> [a] -> ([a], [a])
go [a]
trues [a]
falses (Bool
True  : [Bool]
bs) (a
x : [a]
xs) = [a] -> [a] -> [Bool] -> [a] -> ([a], [a])
go (a
xforall a. a -> [a] -> [a]
:[a]
trues) [a]
falses [Bool]
bs [a]
xs
    go [a]
trues [a]
falses (Bool
False : [Bool]
bs) (a
x : [a]
xs) = [a] -> [a] -> [Bool] -> [a] -> ([a], [a])
go [a]
trues (a
xforall a. a -> [a] -> [a]
:[a]
falses) [Bool]
bs [a]
xs
    go [a]
trues [a]
falses [Bool]
_ [a]
_ = (forall a. [a] -> [a]
reverse [a]
trues, forall a. [a] -> [a]
reverse [a]
falses)

stretchZipWith :: (a -> Bool) -> b -> (a->b->c) -> [a] -> [b] -> [c]
-- ^ @stretchZipWith p z f xs ys@ stretches @ys@ by inserting @z@ in
-- the places where @p@ returns @True@

stretchZipWith :: forall a b c.
(a -> Bool) -> b -> (a -> b -> c) -> [a] -> [b] -> [c]
stretchZipWith a -> Bool
_ b
_ a -> b -> c
_ []     [b]
_ = []
stretchZipWith a -> Bool
p b
z a -> b -> c
f (a
x:[a]
xs) [b]
ys
  | a -> Bool
p a
x       = a -> b -> c
f a
x b
z forall a. a -> [a] -> [a]
: forall a b c.
(a -> Bool) -> b -> (a -> b -> c) -> [a] -> [b] -> [c]
stretchZipWith a -> Bool
p b
z a -> b -> c
f [a]
xs [b]
ys
  | Bool
otherwise = case [b]
ys of
                []     -> []
                (b
y:[b]
ys) -> a -> b -> c
f a
x b
y forall a. a -> [a] -> [a]
: forall a b c.
(a -> Bool) -> b -> (a -> b -> c) -> [a] -> [b] -> [c]
stretchZipWith a -> Bool
p b
z a -> b -> c
f [a]
xs [b]
ys

mapFst :: (a->c) -> [(a,b)] -> [(c,b)]
mapSnd :: (b->c) -> [(a,b)] -> [(a,c)]

mapFst :: forall a c b. (a -> c) -> [(a, b)] -> [(c, b)]
mapFst a -> c
f [(a, b)]
xys = [(a -> c
f a
x, b
y) | (a
x,b
y) <- [(a, b)]
xys]
mapSnd :: forall b c a. (b -> c) -> [(a, b)] -> [(a, c)]
mapSnd b -> c
f [(a, b)]
xys = [(a
x, b -> c
f b
y) | (a
x,b
y) <- [(a, b)]
xys]

mapAndUnzip :: (a -> (b, c)) -> [a] -> ([b], [c])

mapAndUnzip :: forall a b c. (a -> (b, c)) -> [a] -> ([b], [c])
mapAndUnzip a -> (b, c)
_ [] = ([], [])
mapAndUnzip a -> (b, c)
f (a
x:[a]
xs)
  = let (b
r1,  c
r2)  = a -> (b, c)
f a
x
        ([b]
rs1, [c]
rs2) = forall a b c. (a -> (b, c)) -> [a] -> ([b], [c])
mapAndUnzip a -> (b, c)
f [a]
xs
    in
    (b
r1forall a. a -> [a] -> [a]
:[b]
rs1, c
r2forall a. a -> [a] -> [a]
:[c]
rs2)

mapAndUnzip3 :: (a -> (b, c, d)) -> [a] -> ([b], [c], [d])

mapAndUnzip3 :: forall a b c d. (a -> (b, c, d)) -> [a] -> ([b], [c], [d])
mapAndUnzip3 a -> (b, c, d)
_ [] = ([], [], [])
mapAndUnzip3 a -> (b, c, d)
f (a
x:[a]
xs)
  = let (b
r1,  c
r2,  d
r3)  = a -> (b, c, d)
f a
x
        ([b]
rs1, [c]
rs2, [d]
rs3) = forall a b c d. (a -> (b, c, d)) -> [a] -> ([b], [c], [d])
mapAndUnzip3 a -> (b, c, d)
f [a]
xs
    in
    (b
r1forall a. a -> [a] -> [a]
:[b]
rs1, c
r2forall a. a -> [a] -> [a]
:[c]
rs2, d
r3forall a. a -> [a] -> [a]
:[d]
rs3)

zipWithAndUnzip :: (a -> b -> (c,d)) -> [a] -> [b] -> ([c],[d])
zipWithAndUnzip :: forall a b c d. (a -> b -> (c, d)) -> [a] -> [b] -> ([c], [d])
zipWithAndUnzip a -> b -> (c, d)
f (a
a:[a]
as) (b
b:[b]
bs)
  = let (c
r1,  d
r2)  = a -> b -> (c, d)
f a
a b
b
        ([c]
rs1, [d]
rs2) = forall a b c d. (a -> b -> (c, d)) -> [a] -> [b] -> ([c], [d])
zipWithAndUnzip a -> b -> (c, d)
f [a]
as [b]
bs
    in
    (c
r1forall a. a -> [a] -> [a]
:[c]
rs1, d
r2forall a. a -> [a] -> [a]
:[d]
rs2)
zipWithAndUnzip a -> b -> (c, d)
_ [a]
_ [b]
_ = ([],[])

-- | This has the effect of making the two lists have equal length by dropping
-- the tail of the longer one.
zipAndUnzip :: [a] -> [b] -> ([a],[b])
zipAndUnzip :: forall a b. [a] -> [b] -> ([a], [b])
zipAndUnzip (a
a:[a]
as) (b
b:[b]
bs)
  = let ([a]
rs1, [b]
rs2) = forall a b. [a] -> [b] -> ([a], [b])
zipAndUnzip [a]
as [b]
bs
    in
    (a
aforall a. a -> [a] -> [a]
:[a]
rs1, b
bforall a. a -> [a] -> [a]
:[b]
rs2)
zipAndUnzip [a]
_ [b]
_ = ([],[])

-- | @atLength atLen atEnd ls n@ unravels list @ls@ to position @n@. Precisely:
--
-- @
--  atLength atLenPred atEndPred ls n
--   | n < 0         = atLenPred ls
--   | length ls < n = atEndPred (n - length ls)
--   | otherwise     = atLenPred (drop n ls)
-- @
atLength :: ([a] -> b)   -- Called when length ls >= n, passed (drop n ls)
                         --    NB: arg passed to this function may be []
         -> b            -- Called when length ls <  n
         -> [a]
         -> Int
         -> b
atLength :: forall a b. ([a] -> b) -> b -> [a] -> Int -> b
atLength [a] -> b
atLenPred b
atEnd [a]
ls0 Int
n0
  | Int
n0 forall a. Ord a => a -> a -> Bool
< Int
0    = [a] -> b
atLenPred [a]
ls0
  | Bool
otherwise = Int -> [a] -> b
go Int
n0 [a]
ls0
  where
    -- go's first arg n >= 0
    go :: Int -> [a] -> b
go Int
0 [a]
ls     = [a] -> b
atLenPred [a]
ls
    go Int
_ []     = b
atEnd           -- n > 0 here
    go Int
n (a
_:[a]
xs) = Int -> [a] -> b
go (Int
nforall a. Num a => a -> a -> a
-Int
1) [a]
xs

-- Some special cases of atLength:

-- | @(lengthExceeds xs n) = (length xs > n)@
lengthExceeds :: [a] -> Int -> Bool
lengthExceeds :: forall a. [a] -> Int -> Bool
lengthExceeds [a]
lst Int
n
  | Int
n forall a. Ord a => a -> a -> Bool
< Int
0
  = Bool
True
  | Bool
otherwise
  = forall a b. ([a] -> b) -> b -> [a] -> Int -> b
atLength forall (f :: * -> *) a. Foldable f => f a -> Bool
notNull Bool
False [a]
lst Int
n

-- | @(lengthAtLeast xs n) = (length xs >= n)@
lengthAtLeast :: [a] -> Int -> Bool
lengthAtLeast :: forall a. [a] -> Int -> Bool
lengthAtLeast = forall a b. ([a] -> b) -> b -> [a] -> Int -> b
atLength (forall a b. a -> b -> a
const Bool
True) Bool
False

-- | @(lengthIs xs n) = (length xs == n)@
lengthIs :: [a] -> Int -> Bool
lengthIs :: forall a. [a] -> Int -> Bool
lengthIs [a]
lst Int
n
  | Int
n forall a. Ord a => a -> a -> Bool
< Int
0
  = Bool
False
  | Bool
otherwise
  = forall a b. ([a] -> b) -> b -> [a] -> Int -> b
atLength forall (t :: * -> *) a. Foldable t => t a -> Bool
null Bool
False [a]
lst Int
n

-- | @(lengthIsNot xs n) = (length xs /= n)@
lengthIsNot :: [a] -> Int -> Bool
lengthIsNot :: forall a. [a] -> Int -> Bool
lengthIsNot [a]
lst Int
n
  | Int
n forall a. Ord a => a -> a -> Bool
< Int
0 = Bool
True
  | Bool
otherwise = forall a b. ([a] -> b) -> b -> [a] -> Int -> b
atLength forall (f :: * -> *) a. Foldable f => f a -> Bool
notNull Bool
True [a]
lst Int
n

-- | @(lengthAtMost xs n) = (length xs <= n)@
lengthAtMost :: [a] -> Int -> Bool
lengthAtMost :: forall a. [a] -> Int -> Bool
lengthAtMost [a]
lst Int
n
  | Int
n forall a. Ord a => a -> a -> Bool
< Int
0
  = Bool
False
  | Bool
otherwise
  = forall a b. ([a] -> b) -> b -> [a] -> Int -> b
atLength forall (t :: * -> *) a. Foldable t => t a -> Bool
null Bool
True [a]
lst Int
n

-- | @(lengthLessThan xs n) == (length xs < n)@
lengthLessThan :: [a] -> Int -> Bool
lengthLessThan :: forall a. [a] -> Int -> Bool
lengthLessThan = forall a b. ([a] -> b) -> b -> [a] -> Int -> b
atLength (forall a b. a -> b -> a
const Bool
False) Bool
True

listLengthCmp :: [a] -> Int -> Ordering
listLengthCmp :: forall a. [a] -> Int -> Ordering
listLengthCmp = forall a b. ([a] -> b) -> b -> [a] -> Int -> b
atLength forall {a}. [a] -> Ordering
atLen Ordering
atEnd
 where
  atEnd :: Ordering
atEnd = Ordering
LT    -- Not yet seen 'n' elts, so list length is < n.

  atLen :: [a] -> Ordering
atLen []     = Ordering
EQ
  atLen [a]
_      = Ordering
GT

equalLength :: [a] -> [b] -> Bool
-- ^ True if length xs == length ys
equalLength :: forall a b. [a] -> [b] -> Bool
equalLength []     []     = Bool
True
equalLength (a
_:[a]
xs) (b
_:[b]
ys) = forall a b. [a] -> [b] -> Bool
equalLength [a]
xs [b]
ys
equalLength [a]
_      [b]
_      = Bool
False

compareLength :: [a] -> [b] -> Ordering
compareLength :: forall a b. [a] -> [b] -> Ordering
compareLength []     []     = Ordering
EQ
compareLength (a
_:[a]
xs) (b
_:[b]
ys) = forall a b. [a] -> [b] -> Ordering
compareLength [a]
xs [b]
ys
compareLength []     [b]
_      = Ordering
LT
compareLength [a]
_      []     = Ordering
GT

leLength :: [a] -> [b] -> Bool
-- ^ True if length xs <= length ys
leLength :: forall a b. [a] -> [b] -> Bool
leLength [a]
xs [b]
ys = case forall a b. [a] -> [b] -> Ordering
compareLength [a]
xs [b]
ys of
                   Ordering
LT -> Bool
True
                   Ordering
EQ -> Bool
True
                   Ordering
GT -> Bool
False

ltLength :: [a] -> [b] -> Bool
-- ^ True if length xs < length ys
ltLength :: forall a b. [a] -> [b] -> Bool
ltLength [a]
xs [b]
ys = case forall a b. [a] -> [b] -> Ordering
compareLength [a]
xs [b]
ys of
                   Ordering
LT -> Bool
True
                   Ordering
EQ -> Bool
False
                   Ordering
GT -> Bool
False

----------------------------
singleton :: a -> [a]
singleton :: forall a. a -> [a]
singleton a
x = [a
x]

isSingleton :: [a] -> Bool
isSingleton :: forall a. [a] -> Bool
isSingleton [a
_] = Bool
True
isSingleton [a]
_   = Bool
False

notNull :: Foldable f => f a -> Bool
notNull :: forall (f :: * -> *) a. Foldable f => f a -> Bool
notNull = Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> Bool
null

only :: [a] -> a
#if defined(DEBUG)
only [a] = a
#else
only :: forall a. [a] -> a
only (a
a:[a]
_) = a
a
#endif
only [a]
_ = forall a. String -> a
panic String
"Util: only"

-- Debugging/specialising versions of \tr{elem} and \tr{notElem}

# if !defined(DEBUG)
isIn, isn'tIn :: Eq a => String -> a -> [a] -> Bool
isIn :: forall a. Eq a => String -> a -> [a] -> Bool
isIn    String
_msg a
x [a]
ys = a
x forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [a]
ys
isn'tIn :: forall a. Eq a => String -> a -> [a] -> Bool
isn'tIn String
_msg a
x [a]
ys = a
x forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [a]
ys

# else /* DEBUG */
isIn, isn'tIn :: (HasDebugCallStack, Eq a) => String -> a -> [a] -> Bool
isIn msg x ys
  = elem100 0 x ys
  where
    elem100 :: Eq a => Int -> a -> [a] -> Bool
    elem100 _ _ [] = False
    elem100 i x (y:ys)
      | i > 100 = WARN(True, text ("Over-long elem in " ++ msg)) (x `elem` (y:ys))
      | otherwise = x == y || elem100 (i + 1) x ys

isn'tIn msg x ys
  = notElem100 0 x ys
  where
    notElem100 :: Eq a => Int -> a -> [a] -> Bool
    notElem100 _ _ [] =  True
    notElem100 i x (y:ys)
      | i > 100 = WARN(True, text ("Over-long notElem in " ++ msg)) (x `notElem` (y:ys))
      | otherwise = x /= y && notElem100 (i + 1) x ys
# endif /* DEBUG */


-- | Split a list into chunks of /n/ elements
chunkList :: Int -> [a] -> [[a]]
chunkList :: forall a. Int -> [a] -> [[a]]
chunkList Int
_ [] = []
chunkList Int
n [a]
xs = [a]
as forall a. a -> [a] -> [a]
: forall a. Int -> [a] -> [[a]]
chunkList Int
n [a]
bs where ([a]
as,[a]
bs) = forall a. Int -> [a] -> ([a], [a])
splitAt Int
n [a]
xs

-- | Replace the last element of a list with another element.
changeLast :: [a] -> a -> [a]
changeLast :: forall a. [a] -> a -> [a]
changeLast []     a
_  = forall a. String -> a
panic String
"changeLast"
changeLast [a
_]    a
x  = [a
x]
changeLast (a
x:[a]
xs) a
x' = a
x forall a. a -> [a] -> [a]
: forall a. [a] -> a -> [a]
changeLast [a]
xs a
x'

-- | Apply an effectful function to the last list element.
-- Assumes a non-empty list (panics otherwise).
mapLastM :: Functor f => (a -> f a) -> [a] -> f [a]
mapLastM :: forall (f :: * -> *) a. Functor f => (a -> f a) -> [a] -> f [a]
mapLastM a -> f a
_ [] = forall a. String -> a
panic String
"mapLastM: empty list"
mapLastM a -> f a
f [a
x] = (\a
x' -> [a
x']) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f a
f a
x
mapLastM a -> f a
f (a
x:[a]
xs) = (a
xforall a. a -> [a] -> [a]
:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (f :: * -> *) a. Functor f => (a -> f a) -> [a] -> f [a]
mapLastM a -> f a
f [a]
xs

whenNonEmpty :: Applicative m => [a] -> (NonEmpty a -> m ()) -> m ()
whenNonEmpty :: forall (m :: * -> *) a.
Applicative m =>
[a] -> (NonEmpty a -> m ()) -> m ()
whenNonEmpty []     NonEmpty a -> m ()
_ = forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
whenNonEmpty (a
x:[a]
xs) NonEmpty a -> m ()
f = NonEmpty a -> m ()
f (a
x forall a. a -> [a] -> NonEmpty a
:| [a]
xs)

-- | Merge an unsorted list of sorted lists, for example:
--
--  > mergeListsBy compare [ [2,5,15], [1,10,100] ] = [1,2,5,10,15,100]
--
--  \( O(n \log{} k) \)
mergeListsBy :: forall a. (a -> a -> Ordering) -> [[a]] -> [a]
mergeListsBy :: forall a. (a -> a -> Ordering) -> [[a]] -> [a]
mergeListsBy a -> a -> Ordering
cmp [[a]]
lists | Bool
debugIsOn, Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all [a] -> Bool
sorted [[a]]
lists) =
  -- When debugging is on, we check that the input lists are sorted.
  forall a. String -> a
panic String
"mergeListsBy: input lists must be sorted"
  where sorted :: [a] -> Bool
sorted = forall a. (a -> a -> Ordering) -> [a] -> Bool
isSortedBy a -> a -> Ordering
cmp
mergeListsBy a -> a -> Ordering
cmp [[a]]
all_lists = [[a]] -> [a]
merge_lists [[a]]
all_lists
  where
    -- Implements "Iterative 2-Way merge" described at
    -- https://en.wikipedia.org/wiki/K-way_merge_algorithm

    -- Merge two sorted lists into one in O(n).
    merge2 :: [a] -> [a] -> [a]
    merge2 :: [a] -> [a] -> [a]
merge2 [] [a]
ys = [a]
ys
    merge2 [a]
xs [] = [a]
xs
    merge2 (a
x:[a]
xs) (a
y:[a]
ys) =
      case a -> a -> Ordering
cmp a
x a
y of
        Ordering
GT -> a
y forall a. a -> [a] -> [a]
: [a] -> [a] -> [a]
merge2 (a
xforall a. a -> [a] -> [a]
:[a]
xs) [a]
ys
        Ordering
_  -> a
x forall a. a -> [a] -> [a]
: [a] -> [a] -> [a]
merge2 [a]
xs (a
yforall a. a -> [a] -> [a]
:[a]
ys)

    -- Merge the first list with the second, the third with the fourth, and so
    -- on. The output has half as much lists as the input.
    merge_neighbours :: [[a]] -> [[a]]
    merge_neighbours :: [[a]] -> [[a]]
merge_neighbours []   = []
    merge_neighbours [[a]
xs] = [[a]
xs]
    merge_neighbours ([a]
xs : [a]
ys : [[a]]
lists) =
      [a] -> [a] -> [a]
merge2 [a]
xs [a]
ys forall a. a -> [a] -> [a]
: [[a]] -> [[a]]
merge_neighbours [[a]]
lists

    -- Since 'merge_neighbours' halves the amount of lists in each iteration,
    -- we perform O(log k) iteration. Each iteration is O(n). The total running
    -- time is therefore O(n log k).
    merge_lists :: [[a]] -> [a]
    merge_lists :: [[a]] -> [a]
merge_lists [[a]]
lists =
      case [[a]] -> [[a]]
merge_neighbours [[a]]
lists of
        []     -> []
        [[a]
xs]   -> [a]
xs
        [[a]]
lists' -> [[a]] -> [a]
merge_lists [[a]]
lists'

isSortedBy :: (a -> a -> Ordering) -> [a] -> Bool
isSortedBy :: forall a. (a -> a -> Ordering) -> [a] -> Bool
isSortedBy a -> a -> Ordering
cmp = [a] -> Bool
sorted
  where
    sorted :: [a] -> Bool
sorted [] = Bool
True
    sorted [a
_] = Bool
True
    sorted (a
x:a
y:[a]
xs) = a -> a -> Ordering
cmp a
x a
y forall a. Eq a => a -> a -> Bool
/= Ordering
GT Bool -> Bool -> Bool
&& [a] -> Bool
sorted (a
yforall a. a -> [a] -> [a]
:[a]
xs)
{-
************************************************************************
*                                                                      *
\subsubsection{Sort utils}
*                                                                      *
************************************************************************
-}

minWith :: Ord b => (a -> b) -> [a] -> a
minWith :: forall b a. Ord b => (a -> b) -> [a] -> a
minWith a -> b
get_key [a]
xs = ASSERT( not (null xs) )
                     forall a. [a] -> a
head (forall b a. Ord b => (a -> b) -> [a] -> [a]
sortWith a -> b
get_key [a]
xs)

nubSort :: Ord a => [a] -> [a]
nubSort :: forall a. Ord a => [a] -> [a]
nubSort = forall a. Set a -> [a]
Set.toAscList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Ord a => [a] -> Set a
Set.fromList

-- | Remove duplicates but keep elements in order.
--   O(n * log n)
ordNub :: Ord a => [a] -> [a]
ordNub :: forall a. Ord a => [a] -> [a]
ordNub [a]
xs
  = forall {a}. Ord a => Set a -> [a] -> [a]
go forall a. Set a
Set.empty [a]
xs
  where
    go :: Set a -> [a] -> [a]
go Set a
_ [] = []
    go Set a
s (a
x:[a]
xs)
      | forall a. Ord a => a -> Set a -> Bool
Set.member a
x Set a
s = Set a -> [a] -> [a]
go Set a
s [a]
xs
      | Bool
otherwise = a
x forall a. a -> [a] -> [a]
: Set a -> [a] -> [a]
go (forall a. Ord a => a -> Set a -> Set a
Set.insert a
x Set a
s) [a]
xs


{-
************************************************************************
*                                                                      *
\subsection[Utils-transitive-closure]{Transitive closure}
*                                                                      *
************************************************************************

This algorithm for transitive closure is straightforward, albeit quadratic.
-}

transitiveClosure :: (a -> [a])         -- Successor function
                  -> (a -> a -> Bool)   -- Equality predicate
                  -> [a]
                  -> [a]                -- The transitive closure

transitiveClosure :: forall a. (a -> [a]) -> (a -> a -> Bool) -> [a] -> [a]
transitiveClosure a -> [a]
succ a -> a -> Bool
eq [a]
xs
 = [a] -> [a] -> [a]
go [] [a]
xs
 where
   go :: [a] -> [a] -> [a]
go [a]
done []                      = [a]
done
   go [a]
done (a
x:[a]
xs) | a
x a -> [a] -> Bool
`is_in` [a]
done = [a] -> [a] -> [a]
go [a]
done [a]
xs
                  | Bool
otherwise      = [a] -> [a] -> [a]
go (a
xforall a. a -> [a] -> [a]
:[a]
done) (a -> [a]
succ a
x forall a. [a] -> [a] -> [a]
++ [a]
xs)

   a
_ is_in :: a -> [a] -> Bool
`is_in` []                 = Bool
False
   a
x `is_in` (a
y:[a]
ys) | a -> a -> Bool
eq a
x a
y    = Bool
True
                    | Bool
otherwise = a
x a -> [a] -> Bool
`is_in` [a]
ys

{-
************************************************************************
*                                                                      *
\subsection[Utils-accum]{Accumulating}
*                                                                      *
************************************************************************

A combination of foldl with zip.  It works with equal length lists.
-}

foldl2 :: (acc -> a -> b -> acc) -> acc -> [a] -> [b] -> acc
foldl2 :: forall acc a b. (acc -> a -> b -> acc) -> acc -> [a] -> [b] -> acc
foldl2 acc -> a -> b -> acc
_ acc
z [] [] = acc
z
foldl2 acc -> a -> b -> acc
k acc
z (a
a:[a]
as) (b
b:[b]
bs) = forall acc a b. (acc -> a -> b -> acc) -> acc -> [a] -> [b] -> acc
foldl2 acc -> a -> b -> acc
k (acc -> a -> b -> acc
k acc
z a
a b
b) [a]
as [b]
bs
foldl2 acc -> a -> b -> acc
_ acc
_ [a]
_      [b]
_      = forall a. String -> a
panic String
"Util: foldl2"

all2 :: (a -> b -> Bool) -> [a] -> [b] -> Bool
-- True if the lists are the same length, and
-- all corresponding elements satisfy the predicate
all2 :: forall a b. (a -> b -> Bool) -> [a] -> [b] -> Bool
all2 a -> b -> Bool
_ []     []     = Bool
True
all2 a -> b -> Bool
p (a
x:[a]
xs) (b
y:[b]
ys) = a -> b -> Bool
p a
x b
y Bool -> Bool -> Bool
&& forall a b. (a -> b -> Bool) -> [a] -> [b] -> Bool
all2 a -> b -> Bool
p [a]
xs [b]
ys
all2 a -> b -> Bool
_ [a]
_      [b]
_      = Bool
False

-- Count the number of times a predicate is true

count :: (a -> Bool) -> [a] -> Int
count :: forall a. (a -> Bool) -> [a] -> Int
count a -> Bool
p = Int -> [a] -> Int
go Int
0
  where go :: Int -> [a] -> Int
go !Int
n [] = Int
n
        go !Int
n (a
x:[a]
xs) | a -> Bool
p a
x       = Int -> [a] -> Int
go (Int
nforall a. Num a => a -> a -> a
+Int
1) [a]
xs
                     | Bool
otherwise = Int -> [a] -> Int
go Int
n [a]
xs

countWhile :: (a -> Bool) -> [a] -> Int
-- Length of an /initial prefix/ of the list satisfying p
countWhile :: forall a. (a -> Bool) -> [a] -> Int
countWhile a -> Bool
p = Int -> [a] -> Int
go Int
0
  where go :: Int -> [a] -> Int
go !Int
n (a
x:[a]
xs) | a -> Bool
p a
x = Int -> [a] -> Int
go (Int
nforall a. Num a => a -> a -> a
+Int
1) [a]
xs
        go !Int
n [a]
_            = Int
n

{-
@splitAt@, @take@, and @drop@ but with length of another
list giving the break-off point:
-}

takeList :: [b] -> [a] -> [a]
-- (takeList as bs) trims bs to the be same length
-- as as, unless as is longer in which case it's a no-op
takeList :: forall b a. [b] -> [a] -> [a]
takeList [] [a]
_ = []
takeList (b
_:[b]
xs) [a]
ls =
   case [a]
ls of
     [] -> []
     (a
y:[a]
ys) -> a
y forall a. a -> [a] -> [a]
: forall b a. [b] -> [a] -> [a]
takeList [b]
xs [a]
ys

dropList :: [b] -> [a] -> [a]
dropList :: forall b a. [b] -> [a] -> [a]
dropList [] [a]
xs    = [a]
xs
dropList [b]
_  xs :: [a]
xs@[] = [a]
xs
dropList (b
_:[b]
xs) (a
_:[a]
ys) = forall b a. [b] -> [a] -> [a]
dropList [b]
xs [a]
ys


-- | Given two lists xs and ys, return `splitAt (length xs) ys`.
splitAtList :: [b] -> [a] -> ([a], [a])
splitAtList :: forall b a. [b] -> [a] -> ([a], [a])
splitAtList [b]
xs [a]
ys = Int# -> [b] -> [a] -> ([a], [a])
go Int#
0# [b]
xs [a]
ys
   where
      -- we are careful to avoid allocating when there are no leftover
      -- arguments: in this case we can return "ys" directly (cf #18535)
      --
      -- We make `xs` strict because in the general case `ys` isn't `[]` so we
      -- will have to evaluate `xs` anyway.
      go :: Int# -> [b] -> [a] -> ([a], [a])
go Int#
_  ![b]
_     []     = ([a]
ys, [])             -- length ys <= length xs
      go Int#
n  []     [a]
bs     = (forall a. Int -> [a] -> [a]
take (Int# -> Int
I# Int#
n) [a]
ys, [a]
bs) -- = splitAt n ys
      go Int#
n  (b
_:[b]
as) (a
_:[a]
bs) = Int# -> [b] -> [a] -> ([a], [a])
go (Int#
n Int# -> Int# -> Int#
+# Int#
1#) [b]
as [a]
bs

-- drop from the end of a list
dropTail :: Int -> [a] -> [a]
-- Specification: dropTail n = reverse . drop n . reverse
-- Better implementation due to Joachim Breitner
-- http://www.joachim-breitner.de/blog/archives/600-On-taking-the-last-n-elements-of-a-list.html
dropTail :: forall a. Int -> [a] -> [a]
dropTail Int
n [a]
xs
  = forall b a. [b] -> [a] -> [a]
go (forall a. Int -> [a] -> [a]
drop Int
n [a]
xs) [a]
xs
  where
    go :: [a] -> [a] -> [a]
go (a
_:[a]
ys) (a
x:[a]
xs) = a
x forall a. a -> [a] -> [a]
: [a] -> [a] -> [a]
go [a]
ys [a]
xs
    go [a]
_      [a]
_      = []  -- Stop when ys runs out
                           -- It'll always run out before xs does

-- dropWhile from the end of a list. This is similar to Data.List.dropWhileEnd,
-- but is lazy in the elements and strict in the spine. For reasonably short lists,
-- such as path names and typical lines of text, dropWhileEndLE is generally
-- faster than dropWhileEnd. Its advantage is magnified when the predicate is
-- expensive--using dropWhileEndLE isSpace to strip the space off a line of text
-- is generally much faster than using dropWhileEnd isSpace for that purpose.
-- Specification: dropWhileEndLE p = reverse . dropWhile p . reverse
-- Pay attention to the short-circuit (&&)! The order of its arguments is the only
-- difference between dropWhileEnd and dropWhileEndLE.
dropWhileEndLE :: (a -> Bool) -> [a] -> [a]
dropWhileEndLE :: forall a. (a -> Bool) -> [a] -> [a]
dropWhileEndLE a -> Bool
p = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\a
x [a]
r -> if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
r Bool -> Bool -> Bool
&& a -> Bool
p a
x then [] else a
xforall a. a -> [a] -> [a]
:[a]
r) []

-- | @spanEnd p l == reverse (span p (reverse l))@. The first list
-- returns actually comes after the second list (when you look at the
-- input list).
spanEnd :: (a -> Bool) -> [a] -> ([a], [a])
spanEnd :: forall a. (a -> Bool) -> [a] -> ([a], [a])
spanEnd a -> Bool
p [a]
l = [a] -> [a] -> [a] -> [a] -> ([a], [a])
go [a]
l [] [] [a]
l
  where go :: [a] -> [a] -> [a] -> [a] -> ([a], [a])
go [a]
yes [a]
_rev_yes [a]
rev_no [] = ([a]
yes, forall a. [a] -> [a]
reverse [a]
rev_no)
        go [a]
yes [a]
rev_yes  [a]
rev_no (a
x:[a]
xs)
          | a -> Bool
p a
x       = [a] -> [a] -> [a] -> [a] -> ([a], [a])
go [a]
yes (a
x forall a. a -> [a] -> [a]
: [a]
rev_yes) [a]
rev_no                  [a]
xs
          | Bool
otherwise = [a] -> [a] -> [a] -> [a] -> ([a], [a])
go [a]
xs  []            (a
x forall a. a -> [a] -> [a]
: [a]
rev_yes forall a. [a] -> [a] -> [a]
++ [a]
rev_no) [a]
xs

-- | Get the last two elements in a list. Partial!
{-# INLINE last2 #-}
last2 :: [a] -> (a,a)
last2 :: forall a. [a] -> (a, a)
last2 = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' (\(a
_,a
x2) a
x -> (a
x2,a
x)) (forall {a}. a
partialError,forall {a}. a
partialError)
  where
    partialError :: a
partialError = forall a. String -> a
panic String
"last2 - list length less than two"

lastMaybe :: [a] -> Maybe a
lastMaybe :: forall a. [a] -> Maybe a
lastMaybe [] = forall a. Maybe a
Nothing
lastMaybe [a]
xs = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
last [a]
xs

-- | Split a list into its last element and the initial part of the list.
-- @snocView xs = Just (init xs, last xs)@ for non-empty lists.
-- @snocView xs = Nothing@ otherwise.
-- Unless both parts of the result are guaranteed to be used
-- prefer separate calls to @last@ + @init@.
-- If you are guaranteed to use both, this will
-- be more efficient.
snocView :: [a] -> Maybe ([a],a)
snocView :: forall a. [a] -> Maybe ([a], a)
snocView [] = forall a. Maybe a
Nothing
snocView [a]
xs
    | ([a]
xs,a
x) <- forall a. [a] -> ([a], a)
go [a]
xs
    = forall a. a -> Maybe a
Just ([a]
xs,a
x)
  where
    go :: [a] -> ([a],a)
    go :: forall a. [a] -> ([a], a)
go [a
x] = ([],a
x)
    go (a
x:[a]
xs)
        | !([a]
xs',a
x') <- forall a. [a] -> ([a], a)
go [a]
xs
        = (a
xforall a. a -> [a] -> [a]
:[a]
xs', a
x')
    go [] = forall a. HasCallStack => String -> a
error String
"impossible"

split :: Char -> String -> [String]
split :: Char -> String -> [String]
split Char
c String
s = case String
rest of
                []     -> [String
chunk]
                Char
_:String
rest -> String
chunk forall a. a -> [a] -> [a]
: Char -> String -> [String]
split Char
c String
rest
  where (String
chunk, String
rest) = forall a. (a -> Bool) -> [a] -> ([a], [a])
break (forall a. Eq a => a -> a -> Bool
==Char
c) String
s

-- | Convert a word to title case by capitalising the first letter
capitalise :: String -> String
capitalise :: String -> String
capitalise [] = []
capitalise (Char
c:String
cs) = Char -> Char
toUpper Char
c forall a. a -> [a] -> [a]
: String
cs


{-
************************************************************************
*                                                                      *
\subsection[Utils-comparison]{Comparisons}
*                                                                      *
************************************************************************
-}

isEqual :: Ordering -> Bool
-- Often used in (isEqual (a `compare` b))
isEqual :: Ordering -> Bool
isEqual Ordering
GT = Bool
False
isEqual Ordering
EQ = Bool
True
isEqual Ordering
LT = Bool
False

thenCmp :: Ordering -> Ordering -> Ordering
{-# INLINE thenCmp #-}
thenCmp :: Ordering -> Ordering -> Ordering
thenCmp Ordering
EQ       Ordering
ordering = Ordering
ordering
thenCmp Ordering
ordering Ordering
_        = Ordering
ordering

eqListBy :: (a->a->Bool) -> [a] -> [a] -> Bool
eqListBy :: forall a. (a -> a -> Bool) -> [a] -> [a] -> Bool
eqListBy a -> a -> Bool
_  []     []     = Bool
True
eqListBy a -> a -> Bool
eq (a
x:[a]
xs) (a
y:[a]
ys) = a -> a -> Bool
eq a
x a
y Bool -> Bool -> Bool
&& forall a. (a -> a -> Bool) -> [a] -> [a] -> Bool
eqListBy a -> a -> Bool
eq [a]
xs [a]
ys
eqListBy a -> a -> Bool
_  [a]
_      [a]
_      = Bool
False

eqMaybeBy :: (a ->a->Bool) -> Maybe a -> Maybe a -> Bool
eqMaybeBy :: forall a. (a -> a -> Bool) -> Maybe a -> Maybe a -> Bool
eqMaybeBy a -> a -> Bool
_  Maybe a
Nothing  Maybe a
Nothing  = Bool
True
eqMaybeBy a -> a -> Bool
eq (Just a
x) (Just a
y) = a -> a -> Bool
eq a
x a
y
eqMaybeBy a -> a -> Bool
_  Maybe a
_        Maybe a
_        = Bool
False

cmpList :: (a -> a -> Ordering) -> [a] -> [a] -> Ordering
    -- `cmpList' uses a user-specified comparer

cmpList :: forall a. (a -> a -> Ordering) -> [a] -> [a] -> Ordering
cmpList a -> a -> Ordering
_   []     [] = Ordering
EQ
cmpList a -> a -> Ordering
_   []     [a]
_  = Ordering
LT
cmpList a -> a -> Ordering
_   [a]
_      [] = Ordering
GT
cmpList a -> a -> Ordering
cmp (a
a:[a]
as) (a
b:[a]
bs)
  = case a -> a -> Ordering
cmp a
a a
b of { Ordering
EQ -> forall a. (a -> a -> Ordering) -> [a] -> [a] -> Ordering
cmpList a -> a -> Ordering
cmp [a]
as [a]
bs; Ordering
xxx -> Ordering
xxx }

removeSpaces :: String -> String
removeSpaces :: String -> String
removeSpaces = forall a. (a -> Bool) -> [a] -> [a]
dropWhileEndLE Char -> Bool
isSpace forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isSpace

-- Boolean operators lifted to Applicative
(<&&>) :: Applicative f => f Bool -> f Bool -> f Bool
<&&> :: forall (f :: * -> *). Applicative f => f Bool -> f Bool -> f Bool
(<&&>) = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(&&)
infixr 3 <&&> -- same as (&&)

(<||>) :: Applicative f => f Bool -> f Bool -> f Bool
<||> :: forall (f :: * -> *). Applicative f => f Bool -> f Bool -> f Bool
(<||>) = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(||)
infixr 2 <||> -- same as (||)

{-
************************************************************************
*                                                                      *
\subsection{Edit distance}
*                                                                      *
************************************************************************
-}

-- | Find the "restricted" Damerau-Levenshtein edit distance between two strings.
-- See: <http://en.wikipedia.org/wiki/Damerau-Levenshtein_distance>.
-- Based on the algorithm presented in "A Bit-Vector Algorithm for Computing
-- Levenshtein and Damerau Edit Distances" in PSC'02 (Heikki Hyyro).
-- See http://www.cs.uta.fi/~helmu/pubs/psc02.pdf and
--     http://www.cs.uta.fi/~helmu/pubs/PSCerr.html for an explanation
restrictedDamerauLevenshteinDistance :: String -> String -> Int
restrictedDamerauLevenshteinDistance :: String -> String -> Int
restrictedDamerauLevenshteinDistance String
str1 String
str2
  = Int -> Int -> String -> String -> Int
restrictedDamerauLevenshteinDistanceWithLengths Int
m Int
n String
str1 String
str2
  where
    m :: Int
m = forall (t :: * -> *) a. Foldable t => t a -> Int
length String
str1
    n :: Int
n = forall (t :: * -> *) a. Foldable t => t a -> Int
length String
str2

restrictedDamerauLevenshteinDistanceWithLengths
  :: Int -> Int -> String -> String -> Int
restrictedDamerauLevenshteinDistanceWithLengths :: Int -> Int -> String -> String -> Int
restrictedDamerauLevenshteinDistanceWithLengths Int
m Int
n String
str1 String
str2
  | Int
m forall a. Ord a => a -> a -> Bool
<= Int
n
  = if Int
n forall a. Ord a => a -> a -> Bool
<= Int
32 -- n must be larger so this check is sufficient
    then forall bv.
(Bits bv, Num bv) =>
bv -> Int -> Int -> String -> String -> Int
restrictedDamerauLevenshteinDistance' (forall a. HasCallStack => a
undefined :: Word32) Int
m Int
n String
str1 String
str2
    else forall bv.
(Bits bv, Num bv) =>
bv -> Int -> Int -> String -> String -> Int
restrictedDamerauLevenshteinDistance' (forall a. HasCallStack => a
undefined :: Integer) Int
m Int
n String
str1 String
str2

  | Bool
otherwise
  = if Int
m forall a. Ord a => a -> a -> Bool
<= Int
32 -- m must be larger so this check is sufficient
    then forall bv.
(Bits bv, Num bv) =>
bv -> Int -> Int -> String -> String -> Int
restrictedDamerauLevenshteinDistance' (forall a. HasCallStack => a
undefined :: Word32) Int
n Int
m String
str2 String
str1
    else forall bv.
(Bits bv, Num bv) =>
bv -> Int -> Int -> String -> String -> Int
restrictedDamerauLevenshteinDistance' (forall a. HasCallStack => a
undefined :: Integer) Int
n Int
m String
str2 String
str1

restrictedDamerauLevenshteinDistance'
  :: (Bits bv, Num bv) => bv -> Int -> Int -> String -> String -> Int
restrictedDamerauLevenshteinDistance' :: forall bv.
(Bits bv, Num bv) =>
bv -> Int -> Int -> String -> String -> Int
restrictedDamerauLevenshteinDistance' bv
_bv_dummy Int
m Int
n String
str1 String
str2
  | [] <- String
str1 = Int
n
  | Bool
otherwise  = forall {a} {b} {c} {d} {e}. (a, b, c, d, e) -> e
extractAnswer forall a b. (a -> b) -> a -> b
$
                 forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' (forall bv.
(Bits bv, Num bv) =>
IntMap bv
-> bv
-> bv
-> (bv, bv, bv, bv, Int)
-> Char
-> (bv, bv, bv, bv, Int)
restrictedDamerauLevenshteinDistanceWorker
                             (forall bv. (Bits bv, Num bv) => String -> IntMap bv
matchVectors String
str1) bv
top_bit_mask bv
vector_mask)
                        (bv
0, bv
0, bv
m_ones, bv
0, Int
m) String
str2
  where
    m_ones :: bv
m_ones@bv
vector_mask = (bv
2 forall a b. (Num a, Integral b) => a -> b -> a
^ Int
m) forall a. Num a => a -> a -> a
- bv
1
    top_bit_mask :: bv
top_bit_mask = (bv
1 forall a. Bits a => a -> Int -> a
`shiftL` (Int
m forall a. Num a => a -> a -> a
- Int
1)) forall a. a -> a -> a
`asTypeOf` bv
_bv_dummy
    extractAnswer :: (a, b, c, d, e) -> e
extractAnswer (a
_, b
_, c
_, d
_, e
distance) = e
distance

restrictedDamerauLevenshteinDistanceWorker
      :: (Bits bv, Num bv) => IM.IntMap bv -> bv -> bv
      -> (bv, bv, bv, bv, Int) -> Char -> (bv, bv, bv, bv, Int)
restrictedDamerauLevenshteinDistanceWorker :: forall bv.
(Bits bv, Num bv) =>
IntMap bv
-> bv
-> bv
-> (bv, bv, bv, bv, Int)
-> Char
-> (bv, bv, bv, bv, Int)
restrictedDamerauLevenshteinDistanceWorker IntMap bv
str1_mvs bv
top_bit_mask bv
vector_mask
                                           (bv
pm, bv
d0, bv
vp, bv
vn, Int
distance) Char
char2
  = seq :: forall a b. a -> b -> b
seq IntMap bv
str1_mvs forall a b. (a -> b) -> a -> b
$ seq :: forall a b. a -> b -> b
seq bv
top_bit_mask forall a b. (a -> b) -> a -> b
$ seq :: forall a b. a -> b -> b
seq bv
vector_mask forall a b. (a -> b) -> a -> b
$
    seq :: forall a b. a -> b -> b
seq bv
pm' forall a b. (a -> b) -> a -> b
$ seq :: forall a b. a -> b -> b
seq bv
d0' forall a b. (a -> b) -> a -> b
$ seq :: forall a b. a -> b -> b
seq bv
vp' forall a b. (a -> b) -> a -> b
$ seq :: forall a b. a -> b -> b
seq bv
vn' forall a b. (a -> b) -> a -> b
$
    seq :: forall a b. a -> b -> b
seq Int
distance'' forall a b. (a -> b) -> a -> b
$ seq :: forall a b. a -> b -> b
seq Char
char2 forall a b. (a -> b) -> a -> b
$
    (bv
pm', bv
d0', bv
vp', bv
vn', Int
distance'')
  where
    pm' :: bv
pm' = forall a. a -> Int -> IntMap a -> a
IM.findWithDefault bv
0 (Char -> Int
ord Char
char2) IntMap bv
str1_mvs

    d0' :: bv
d0' = ((((forall bv. Bits bv => bv -> bv -> bv
sizedComplement bv
vector_mask bv
d0) forall bv. Bits bv => bv -> bv -> bv
.&. bv
pm') forall a. Bits a => a -> Int -> a
`shiftL` Int
1) forall bv. Bits bv => bv -> bv -> bv
.&. bv
pm)
      forall bv. Bits bv => bv -> bv -> bv
.|. ((((bv
pm' forall bv. Bits bv => bv -> bv -> bv
.&. bv
vp) forall a. Num a => a -> a -> a
+ bv
vp) forall bv. Bits bv => bv -> bv -> bv
.&. bv
vector_mask) forall bv. Bits bv => bv -> bv -> bv
`xor` bv
vp) forall bv. Bits bv => bv -> bv -> bv
.|. bv
pm' forall bv. Bits bv => bv -> bv -> bv
.|. bv
vn
          -- No need to mask the shiftL because of the restricted range of pm

    hp' :: bv
hp' = bv
vn forall bv. Bits bv => bv -> bv -> bv
.|. forall bv. Bits bv => bv -> bv -> bv
sizedComplement bv
vector_mask (bv
d0' forall bv. Bits bv => bv -> bv -> bv
.|. bv
vp)
    hn' :: bv
hn' = bv
d0' forall bv. Bits bv => bv -> bv -> bv
.&. bv
vp

    hp'_shift :: bv
hp'_shift = ((bv
hp' forall a. Bits a => a -> Int -> a
`shiftL` Int
1) forall bv. Bits bv => bv -> bv -> bv
.|. bv
1) forall bv. Bits bv => bv -> bv -> bv
.&. bv
vector_mask
    hn'_shift :: bv
hn'_shift = (bv
hn' forall a. Bits a => a -> Int -> a
`shiftL` Int
1) forall bv. Bits bv => bv -> bv -> bv
.&. bv
vector_mask
    vp' :: bv
vp' = bv
hn'_shift forall bv. Bits bv => bv -> bv -> bv
.|. forall bv. Bits bv => bv -> bv -> bv
sizedComplement bv
vector_mask (bv
d0' forall bv. Bits bv => bv -> bv -> bv
.|. bv
hp'_shift)
    vn' :: bv
vn' = bv
d0' forall bv. Bits bv => bv -> bv -> bv
.&. bv
hp'_shift

    distance' :: Int
distance' = if bv
hp' forall bv. Bits bv => bv -> bv -> bv
.&. bv
top_bit_mask forall a. Eq a => a -> a -> Bool
/= bv
0 then Int
distance forall a. Num a => a -> a -> a
+ Int
1 else Int
distance
    distance'' :: Int
distance'' = if bv
hn' forall bv. Bits bv => bv -> bv -> bv
.&. bv
top_bit_mask forall a. Eq a => a -> a -> Bool
/= bv
0 then Int
distance' forall a. Num a => a -> a -> a
- Int
1 else Int
distance'

sizedComplement :: Bits bv => bv -> bv -> bv
sizedComplement :: forall bv. Bits bv => bv -> bv -> bv
sizedComplement bv
vector_mask bv
vect = bv
vector_mask forall bv. Bits bv => bv -> bv -> bv
`xor` bv
vect

matchVectors :: (Bits bv, Num bv) => String -> IM.IntMap bv
matchVectors :: forall bv. (Bits bv, Num bv) => String -> IntMap bv
matchVectors = forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' forall {a} {a}.
(Bits a, Integral a, Num a) =>
(a, IntMap a) -> Char -> (a, IntMap a)
go (Int
0 :: Int, forall a. IntMap a
IM.empty)
  where
    go :: (a, IntMap a) -> Char -> (a, IntMap a)
go (a
ix, IntMap a
im) Char
char = let ix' :: a
ix' = a
ix forall a. Num a => a -> a -> a
+ a
1
                           im' :: IntMap a
im' = forall a. (a -> a -> a) -> Int -> a -> IntMap a -> IntMap a
IM.insertWith forall bv. Bits bv => bv -> bv -> bv
(.|.) (Char -> Int
ord Char
char) (a
2 forall a b. (Num a, Integral b) => a -> b -> a
^ a
ix) IntMap a
im
                       in seq :: forall a b. a -> b -> b
seq a
ix' forall a b. (a -> b) -> a -> b
$ seq :: forall a b. a -> b -> b
seq IntMap a
im' forall a b. (a -> b) -> a -> b
$ (a
ix', IntMap a
im')

{-# SPECIALIZE INLINE restrictedDamerauLevenshteinDistance'
                      :: Word32 -> Int -> Int -> String -> String -> Int #-}
{-# SPECIALIZE INLINE restrictedDamerauLevenshteinDistance'
                      :: Integer -> Int -> Int -> String -> String -> Int #-}

{-# SPECIALIZE restrictedDamerauLevenshteinDistanceWorker
               :: IM.IntMap Word32 -> Word32 -> Word32
               -> (Word32, Word32, Word32, Word32, Int)
               -> Char -> (Word32, Word32, Word32, Word32, Int) #-}
{-# SPECIALIZE restrictedDamerauLevenshteinDistanceWorker
               :: IM.IntMap Integer -> Integer -> Integer
               -> (Integer, Integer, Integer, Integer, Int)
               -> Char -> (Integer, Integer, Integer, Integer, Int) #-}

{-# SPECIALIZE INLINE sizedComplement :: Word32 -> Word32 -> Word32 #-}
{-# SPECIALIZE INLINE sizedComplement :: Integer -> Integer -> Integer #-}

{-# SPECIALIZE matchVectors :: String -> IM.IntMap Word32 #-}
{-# SPECIALIZE matchVectors :: String -> IM.IntMap Integer #-}

fuzzyMatch :: String -> [String] -> [String]
fuzzyMatch :: String -> [String] -> [String]
fuzzyMatch String
key [String]
vals = forall a. String -> [(String, a)] -> [a]
fuzzyLookup String
key [(String
v,String
v) | String
v <- [String]
vals]

-- | Search for possible matches to the users input in the given list,
-- returning a small number of ranked results
fuzzyLookup :: String -> [(String,a)] -> [a]
fuzzyLookup :: forall a. String -> [(String, a)] -> [a]
fuzzyLookup String
user_entered [(String, a)]
possibilites
  = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ forall a. Int -> [a] -> [a]
take Int
mAX_RESULTS forall a b. (a -> b) -> a -> b
$ forall a. (a -> a -> Ordering) -> [a] -> [a]
List.sortBy (forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing forall a b. (a, b) -> b
snd)
    [ (a
poss_val, Int
distance) | (String
poss_str, a
poss_val) <- [(String, a)]
possibilites
                       , let distance :: Int
distance = String -> String -> Int
restrictedDamerauLevenshteinDistance
                                            String
poss_str String
user_entered
                       , Int
distance forall a. Ord a => a -> a -> Bool
<= Int
fuzzy_threshold ]
  where
    -- Work out an appropriate match threshold:
    -- We report a candidate if its edit distance is <= the threshold,
    -- The threshold is set to about a quarter of the # of characters the user entered
    --   Length    Threshold
    --     1         0          -- Don't suggest *any* candidates
    --     2         1          -- for single-char identifiers
    --     3         1
    --     4         1
    --     5         1
    --     6         2
    --
    fuzzy_threshold :: Int
fuzzy_threshold = forall a b. (RealFrac a, Integral b) => a -> b
truncate forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall (t :: * -> *) a. Foldable t => t a -> Int
length String
user_entered forall a. Num a => a -> a -> a
+ Int
2) forall a. Fractional a => a -> a -> a
/ (Rational
4 :: Rational)
    mAX_RESULTS :: Int
mAX_RESULTS = Int
3

{-
************************************************************************
*                                                                      *
\subsection[Utils-pairs]{Pairs}
*                                                                      *
************************************************************************
-}

unzipWith :: (a -> b -> c) -> [(a, b)] -> [c]
unzipWith :: forall a b c. (a -> b -> c) -> [(a, b)] -> [c]
unzipWith a -> b -> c
f [(a, b)]
pairs = forall a b. (a -> b) -> [a] -> [b]
map ( \ (a
a, b
b) -> a -> b -> c
f a
a b
b ) [(a, b)]
pairs

seqList :: [a] -> b -> b
seqList :: forall a b. [a] -> b -> b
seqList [] b
b = b
b
seqList (a
x:[a]
xs) b
b = a
x seq :: forall a b. a -> b -> b
`seq` forall a b. [a] -> b -> b
seqList [a]
xs b
b

strictMap :: (a -> b) -> [a] -> [b]
strictMap :: forall a b. (a -> b) -> [a] -> [b]
strictMap a -> b
_ [] = []
strictMap a -> b
f (a
x : [a]
xs) =
  let
    !x' :: b
x' = a -> b
f a
x
    !xs' :: [b]
xs' = forall a b. (a -> b) -> [a] -> [b]
strictMap a -> b
f [a]
xs
  in
    b
x' forall a. a -> [a] -> [a]
: [b]
xs'

strictZipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
strictZipWith :: forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
strictZipWith a -> b -> c
_ [] [b]
_ = []
strictZipWith a -> b -> c
_ [a]
_ [] = []
strictZipWith a -> b -> c
f (a
x : [a]
xs) (b
y: [b]
ys) =
  let
    !x' :: c
x' = a -> b -> c
f a
x b
y
    !xs' :: [c]
xs' = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
strictZipWith a -> b -> c
f [a]
xs [b]
ys
  in
    c
x' forall a. a -> [a] -> [a]
: [c]
xs'


-- Module names:

looksLikeModuleName :: String -> Bool
looksLikeModuleName :: String -> Bool
looksLikeModuleName [] = Bool
False
looksLikeModuleName (Char
c:String
cs) = Char -> Bool
isUpper Char
c Bool -> Bool -> Bool
&& String -> Bool
go String
cs
  where go :: String -> Bool
go [] = Bool
True
        go (Char
'.':String
cs) = String -> Bool
looksLikeModuleName String
cs
        go (Char
c:String
cs)   = (Char -> Bool
isAlphaNum Char
c Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
'_' Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
'\'') Bool -> Bool -> Bool
&& String -> Bool
go String
cs

-- Similar to 'parse' for Distribution.Package.PackageName,
-- but we don't want to depend on Cabal.
looksLikePackageName :: String -> Bool
looksLikePackageName :: String -> Bool
looksLikePackageName = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
isAlphaNum forall (f :: * -> *). Applicative f => f Bool -> f Bool -> f Bool
<&&> Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
isDigit)) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> String -> [String]
split Char
'-'

{-
Akin to @Prelude.words@, but acts like the Bourne shell, treating
quoted strings as Haskell Strings, and also parses Haskell [String]
syntax.
-}

getCmd :: String -> Either String             -- Error
                           (String, String) -- (Cmd, Rest)
getCmd :: String -> Either String (String, String)
getCmd String
s = case forall a. (a -> Bool) -> [a] -> ([a], [a])
break Char -> Bool
isSpace forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isSpace String
s of
           ([], String
_) -> forall a b. a -> Either a b
Left (String
"Couldn't find command in " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show String
s)
           (String, String)
res -> forall a b. b -> Either a b
Right (String, String)
res

toCmdArgs :: String -> Either String             -- Error
                              (String, [String]) -- (Cmd, Args)
toCmdArgs :: String -> Either String (String, [String])
toCmdArgs String
s = case String -> Either String (String, String)
getCmd String
s of
              Left String
err -> forall a b. a -> Either a b
Left String
err
              Right (String
cmd, String
s') -> case String -> Either String [String]
toArgs String
s' of
                                 Left String
err -> forall a b. a -> Either a b
Left String
err
                                 Right [String]
args -> forall a b. b -> Either a b
Right (String
cmd, [String]
args)

toArgs :: String -> Either String   -- Error
                           [String] -- Args
toArgs :: String -> Either String [String]
toArgs String
str
    = case forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isSpace String
str of
      s :: String
s@(Char
'[':String
_) -> case forall a. Read a => ReadS a
reads String
s of
                   [([String]
args, String
spaces)]
                    | forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
isSpace String
spaces ->
                       forall a b. b -> Either a b
Right [String]
args
                   [([String], String)]
_ ->
                       forall a b. a -> Either a b
Left (String
"Couldn't read " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show String
str forall a. [a] -> [a] -> [a]
++ String
" as [String]")
      String
s -> String -> Either String [String]
toArgs' String
s
 where
  toArgs' :: String -> Either String [String]
  -- Remove outer quotes:
  -- > toArgs' "\"foo\" \"bar baz\""
  -- Right ["foo", "bar baz"]
  --
  -- Keep inner quotes:
  -- > toArgs' "-DFOO=\"bar baz\""
  -- Right ["-DFOO=\"bar baz\""]
  toArgs' :: String -> Either String [String]
toArgs' String
s = case forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isSpace String
s of
              [] -> forall a b. b -> Either a b
Right []
              (Char
'"' : String
_) -> do
                    -- readAsString removes outer quotes
                    (String
arg, String
rest) <- String -> Either String (String, String)
readAsString String
s
                    (String
argforall a. a -> [a] -> [a]
:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` String -> Either String [String]
toArgs' String
rest
              String
s' -> case forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Char -> Bool
isSpace forall (f :: * -> *). Applicative f => f Bool -> f Bool -> f Bool
<||> (forall a. Eq a => a -> a -> Bool
== Char
'"')) String
s' of
                    (String
argPart1, s'' :: String
s''@(Char
'"':String
_)) -> do
                        (String
argPart2, String
rest) <- String -> Either String (String, String)
readAsString String
s''
                        -- show argPart2 to keep inner quotes
                        ((String
argPart1 forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show String
argPart2)forall a. a -> [a] -> [a]
:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` String -> Either String [String]
toArgs' String
rest
                    (String
arg, String
s'') -> (String
argforall a. a -> [a] -> [a]
:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` String -> Either String [String]
toArgs' String
s''

  readAsString :: String -> Either String (String, String)
  readAsString :: String -> Either String (String, String)
readAsString String
s = case forall a. Read a => ReadS a
reads String
s of
                [(String
arg, String
rest)]
                    -- rest must either be [] or start with a space
                    | forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
isSpace (forall a. Int -> [a] -> [a]
take Int
1 String
rest) ->
                    forall a b. b -> Either a b
Right (String
arg, String
rest)
                [(String, String)]
_ ->
                    forall a b. a -> Either a b
Left (String
"Couldn't read " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show String
s forall a. [a] -> [a] -> [a]
++ String
" as String")
-----------------------------------------------------------------------------
-- Integers

-- | Determine the $\log_2$ of exact powers of 2
exactLog2 :: Integer -> Maybe Integer
exactLog2 :: Integer -> Maybe Integer
exactLog2 Integer
x
   | Integer
x forall a. Ord a => a -> a -> Bool
<= Integer
0                               = forall a. Maybe a
Nothing
   | Integer
x forall a. Ord a => a -> a -> Bool
> forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. Bounded a => a
maxBound :: Int32) = forall a. Maybe a
Nothing
   | Int32
x' forall bv. Bits bv => bv -> bv -> bv
.&. (-Int32
x') forall a. Eq a => a -> a -> Bool
/= Int32
x'                   = forall a. Maybe a
Nothing
   | Bool
otherwise                            = forall a. a -> Maybe a
Just (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
c)
      where
         x' :: Int32
x' = forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
x :: Int32
         c :: Int
c = forall b. FiniteBits b => b -> Int
countTrailingZeros Int32
x'

{-
-- -----------------------------------------------------------------------------
-- Floats
-}

readRational__ :: ReadS Rational -- NB: doesn't handle leading "-"
readRational__ :: ReadS Rational
readRational__ String
r = do
      ((Integer
i, Integer
e), String
t) <- ReadS (Integer, Integer)
readSignificandExponentPair__ String
r
      forall (m :: * -> *) a. Monad m => a -> m a
return ((Integer
iforall a. Integral a => a -> a -> Ratio a
%Integer
1)forall a. Num a => a -> a -> a
*Rational
10forall a b. (Fractional a, Integral b) => a -> b -> a
^^Integer
e, String
t)

readRational :: String -> Rational -- NB: *does* handle a leading "-"
readRational :: String -> Rational
readRational String
top_s
  = case String
top_s of
      Char
'-' : String
xs -> - (String -> Rational
read_me String
xs)
      String
xs       -> String -> Rational
read_me String
xs
  where
    read_me :: String -> Rational
read_me String
s
      = case (do { (Rational
x,String
"") <- ReadS Rational
readRational__ String
s ; forall (m :: * -> *) a. Monad m => a -> m a
return Rational
x }) of
          [Rational
x] -> Rational
x
          []  -> forall a. HasCallStack => String -> a
error (String
"readRational: no parse:"        forall a. [a] -> [a] -> [a]
++ String
top_s)
          [Rational]
_   -> forall a. HasCallStack => String -> a
error (String
"readRational: ambiguous parse:" forall a. [a] -> [a] -> [a]
++ String
top_s)


readSignificandExponentPair__ :: ReadS (Integer, Integer) -- NB: doesn't handle leading "-"
readSignificandExponentPair__ :: ReadS (Integer, Integer)
readSignificandExponentPair__ String
r = do
     (Integer
n,Int
d,String
s) <- String -> [(Integer, Int, String)]
readFix String
r
     (Int
k,String
t)   <- forall {m :: * -> *}. MonadFail m => String -> m (Int, String)
readExp String
s
     let pair :: (Integer, Integer)
pair = (Integer
n, forall a. Integral a => a -> Integer
toInteger (Int
k forall a. Num a => a -> a -> a
- Int
d))
     forall (m :: * -> *) a. Monad m => a -> m a
return ((Integer, Integer)
pair, String
t)
 where
     readFix :: String -> [(Integer, Int, String)]
readFix String
r = do
        (String
ds,String
s)  <- String -> [(String, String)]
lexDecDigits String
r
        (String
ds',String
t) <- forall {m :: * -> *}. Monad m => String -> m (String, String)
lexDotDigits String
s
        forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. Read a => String -> a
read (String
dsforall a. [a] -> [a] -> [a]
++String
ds'), forall (t :: * -> *) a. Foldable t => t a -> Int
length String
ds', String
t)

     readExp :: String -> m (Int, String)
readExp (Char
e:String
s) | Char
e forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
"eE" = forall {m :: * -> *}. MonadFail m => String -> m (Int, String)
readExp' String
s
     readExp String
s                     = forall (m :: * -> *) a. Monad m => a -> m a
return (Int
0,String
s)

     readExp' :: String -> m (Int, String)
readExp' (Char
'+':String
s) = forall {m :: * -> *}. MonadFail m => String -> m (Int, String)
readDec String
s
     readExp' (Char
'-':String
s) = do (Int
k,String
t) <- forall {m :: * -> *}. MonadFail m => String -> m (Int, String)
readDec String
s
                           forall (m :: * -> *) a. Monad m => a -> m a
return (-Int
k,String
t)
     readExp' String
s       = forall {m :: * -> *}. MonadFail m => String -> m (Int, String)
readDec String
s

     readDec :: String -> m (Int, String)
readDec String
s = do
        (String
ds,String
r) <- forall {m :: * -> *}.
MonadFail m =>
(Char -> Bool) -> String -> m (String, String)
nonnull Char -> Bool
isDigit String
s
        forall (m :: * -> *) a. Monad m => a -> m a
return (forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 (\Int
n Int
d -> Int
n forall a. Num a => a -> a -> a
* Int
10 forall a. Num a => a -> a -> a
+ Int
d) [ Char -> Int
ord Char
d forall a. Num a => a -> a -> a
- Char -> Int
ord Char
'0' | Char
d <- String
ds ],
                String
r)

     lexDecDigits :: String -> [(String, String)]
lexDecDigits = forall {m :: * -> *}.
MonadFail m =>
(Char -> Bool) -> String -> m (String, String)
nonnull Char -> Bool
isDigit

     lexDotDigits :: String -> m (String, String)
lexDotDigits (Char
'.':String
s) = forall (m :: * -> *) a. Monad m => a -> m a
return ((Char -> Bool) -> String -> (String, String)
span' Char -> Bool
isDigit String
s)
     lexDotDigits String
s       = forall (m :: * -> *) a. Monad m => a -> m a
return (String
"",String
s)

     nonnull :: (Char -> Bool) -> String -> m (String, String)
nonnull Char -> Bool
p String
s = do (cs :: String
cs@(Char
_:String
_),String
t) <- forall (m :: * -> *) a. Monad m => a -> m a
return ((Char -> Bool) -> String -> (String, String)
span' Char -> Bool
p String
s)
                      forall (m :: * -> *) a. Monad m => a -> m a
return (String
cs,String
t)

     span' :: (Char -> Bool) -> String -> (String, String)
span' Char -> Bool
_ xs :: String
xs@[]         =  (String
xs, String
xs)
     span' Char -> Bool
p xs :: String
xs@(Char
x:String
xs')
               | Char
x forall a. Eq a => a -> a -> Bool
== Char
'_'  = (Char -> Bool) -> String -> (String, String)
span' Char -> Bool
p String
xs'   -- skip "_" (#14473)
               | Char -> Bool
p Char
x       =  let (String
ys,String
zs) = (Char -> Bool) -> String -> (String, String)
span' Char -> Bool
p String
xs' in (Char
xforall a. a -> [a] -> [a]
:String
ys,String
zs)
               | Bool
otherwise =  ([],String
xs)

-- | Parse a string into a significand and exponent.
-- A trivial example might be:
--   ghci> readSignificandExponentPair "1E2"
--   (1,2)
-- In a more complex case we might return a exponent different than that
-- which the user wrote. This is needed in order to use a Integer significand.
--   ghci> readSignificandExponentPair "-1.11E5"
--   (-111,3)
readSignificandExponentPair :: String -> (Integer, Integer) -- NB: *does* handle a leading "-"
readSignificandExponentPair :: String -> (Integer, Integer)
readSignificandExponentPair String
top_s
  = case String
top_s of
      Char
'-' : String
xs -> let (Integer
i, Integer
e) = String -> (Integer, Integer)
read_me String
xs in (-Integer
i, Integer
e)
      String
xs       -> String -> (Integer, Integer)
read_me String
xs
  where
    read_me :: String -> (Integer, Integer)
read_me String
s
      = case (do { ((Integer, Integer)
x,String
"") <- ReadS (Integer, Integer)
readSignificandExponentPair__ String
s ; forall (m :: * -> *) a. Monad m => a -> m a
return (Integer, Integer)
x }) of
          [(Integer, Integer)
x] -> (Integer, Integer)
x
          []  -> forall a. HasCallStack => String -> a
error (String
"readSignificandExponentPair: no parse:"        forall a. [a] -> [a] -> [a]
++ String
top_s)
          [(Integer, Integer)]
_   -> forall a. HasCallStack => String -> a
error (String
"readSignificandExponentPair: ambiguous parse:" forall a. [a] -> [a] -> [a]
++ String
top_s)


readHexRational :: String -> Rational
readHexRational :: String -> Rational
readHexRational String
str =
  case String
str of
    Char
'-' : String
xs -> - (String -> Rational
readMe String
xs)
    String
xs       -> String -> Rational
readMe String
xs
  where
  readMe :: String -> Rational
readMe String
as =
    case String -> Maybe Rational
readHexRational__ String
as of
      Just Rational
n -> Rational
n
      Maybe Rational
_      -> forall a. HasCallStack => String -> a
error (String
"readHexRational: no parse:" forall a. [a] -> [a] -> [a]
++ String
str)


readHexRational__ :: String -> Maybe Rational
readHexRational__ :: String -> Maybe Rational
readHexRational__ (Char
'0' : Char
x : String
rest)
  | Char
x forall a. Eq a => a -> a -> Bool
== Char
'X' Bool -> Bool -> Bool
|| Char
x forall a. Eq a => a -> a -> Bool
== Char
'x' =
  do let (String
front,String
rest2) = (Char -> Bool) -> String -> (String, String)
span' Char -> Bool
isHexDigit String
rest
     forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
front))
     let frontNum :: Integer
frontNum = forall {t :: * -> *} {b}.
(Foldable t, Num b) =>
b -> b -> t Char -> b
steps Integer
16 Integer
0 String
front
     case String
rest2 of
       Char
'.' : String
rest3 ->
          do let (String
back,String
rest4) = (Char -> Bool) -> String -> (String, String)
span' Char -> Bool
isHexDigit String
rest3
             forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
back))
             let backNum :: Integer
backNum = forall {t :: * -> *} {b}.
(Foldable t, Num b) =>
b -> b -> t Char -> b
steps Integer
16 Integer
frontNum String
back
                 exp1 :: Int
exp1    = -Int
4 forall a. Num a => a -> a -> a
* forall (t :: * -> *) a. Foldable t => t a -> Int
length String
back
             case String
rest4 of
               Char
p : String
ps | Char -> Bool
isExp Char
p -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Integer -> Int -> Rational
mk Integer
backNum forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Num a => a -> a -> a
+ Int
exp1)) (forall {a}. Num a => String -> Maybe a
getExp String
ps)
               String
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return (Integer -> Int -> Rational
mk Integer
backNum Int
exp1)
       Char
p : String
ps | Char -> Bool
isExp Char
p -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Integer -> Int -> Rational
mk Integer
frontNum) (forall {a}. Num a => String -> Maybe a
getExp String
ps)
       String
_ -> forall a. Maybe a
Nothing

  where
  isExp :: Char -> Bool
isExp Char
p = Char
p forall a. Eq a => a -> a -> Bool
== Char
'p' Bool -> Bool -> Bool
|| Char
p forall a. Eq a => a -> a -> Bool
== Char
'P'

  getExp :: String -> Maybe a
getExp (Char
'+' : String
ds) = forall {a}. Num a => String -> Maybe a
dec String
ds
  getExp (Char
'-' : String
ds) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Num a => a -> a
negate (forall {a}. Num a => String -> Maybe a
dec String
ds)
  getExp String
ds         = forall {a}. Num a => String -> Maybe a
dec String
ds

  mk :: Integer -> Int -> Rational
  mk :: Integer -> Int -> Rational
mk Integer
n Int
e = forall a. Num a => Integer -> a
fromInteger Integer
n forall a. Num a => a -> a -> a
* Rational
2forall a b. (Fractional a, Integral b) => a -> b -> a
^^Int
e

  dec :: String -> Maybe a
dec String
cs = case (Char -> Bool) -> String -> (String, String)
span' Char -> Bool
isDigit String
cs of
             (String
ds,String
"") | Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
ds) -> forall a. a -> Maybe a
Just (forall {t :: * -> *} {b}.
(Foldable t, Num b) =>
b -> b -> t Char -> b
steps a
10 a
0 String
ds)
             (String, String)
_ -> forall a. Maybe a
Nothing

  steps :: b -> b -> t Char -> b
steps b
base b
n t Char
ds = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' (forall {a}. Num a => a -> a -> Char -> a
step b
base) b
n t Char
ds
  step :: a -> a -> Char -> a
step  a
base a
n Char
d  = a
base forall a. Num a => a -> a -> a
* a
n forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral (Char -> Int
digitToInt Char
d)

  span' :: (Char -> Bool) -> String -> (String, String)
span' Char -> Bool
_ xs :: String
xs@[]         =  (String
xs, String
xs)
  span' Char -> Bool
p xs :: String
xs@(Char
x:String
xs')
            | Char
x forall a. Eq a => a -> a -> Bool
== Char
'_'  = (Char -> Bool) -> String -> (String, String)
span' Char -> Bool
p String
xs'   -- skip "_"  (#14473)
            | Char -> Bool
p Char
x       =  let (String
ys,String
zs) = (Char -> Bool) -> String -> (String, String)
span' Char -> Bool
p String
xs' in (Char
xforall a. a -> [a] -> [a]
:String
ys,String
zs)
            | Bool
otherwise =  ([],String
xs)

readHexRational__ String
_ = forall a. Maybe a
Nothing

-- | Parse a string into a significand and exponent according to
-- the "Hexadecimal Floats in Haskell" proposal.
-- A trivial example might be:
--   ghci> readHexSignificandExponentPair "0x1p+1"
--   (1,1)
-- Behaves similar to readSignificandExponentPair but the base is 16
-- and numbers are given in hexadecimal:
--   ghci> readHexSignificandExponentPair "0xAp-4"
--   (10,-4)
--   ghci> readHexSignificandExponentPair "0x1.2p3"
--   (18,-1)
readHexSignificandExponentPair :: String -> (Integer, Integer)
readHexSignificandExponentPair :: String -> (Integer, Integer)
readHexSignificandExponentPair String
str =
  case String
str of
    Char
'-' : String
xs -> let (Integer
i, Integer
e) = String -> (Integer, Integer)
readMe String
xs in (-Integer
i, Integer
e)
    String
xs       -> String -> (Integer, Integer)
readMe String
xs
  where
  readMe :: String -> (Integer, Integer)
readMe String
as =
    case String -> Maybe (Integer, Integer)
readHexSignificandExponentPair__ String
as of
      Just (Integer, Integer)
n -> (Integer, Integer)
n
      Maybe (Integer, Integer)
_      -> forall a. HasCallStack => String -> a
error (String
"readHexSignificandExponentPair: no parse:" forall a. [a] -> [a] -> [a]
++ String
str)


readHexSignificandExponentPair__ :: String -> Maybe (Integer, Integer)
readHexSignificandExponentPair__ :: String -> Maybe (Integer, Integer)
readHexSignificandExponentPair__ (Char
'0' : Char
x : String
rest)
  | Char
x forall a. Eq a => a -> a -> Bool
== Char
'X' Bool -> Bool -> Bool
|| Char
x forall a. Eq a => a -> a -> Bool
== Char
'x' =
  do let (String
front,String
rest2) = (Char -> Bool) -> String -> (String, String)
span' Char -> Bool
isHexDigit String
rest
     forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
front))
     let frontNum :: Integer
frontNum = forall {t :: * -> *} {b}.
(Foldable t, Num b) =>
b -> b -> t Char -> b
steps Integer
16 Integer
0 String
front
     case String
rest2 of
       Char
'.' : String
rest3 ->
          do let (String
back,String
rest4) = (Char -> Bool) -> String -> (String, String)
span' Char -> Bool
isHexDigit String
rest3
             forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
back))
             let backNum :: Integer
backNum = forall {t :: * -> *} {b}.
(Foldable t, Num b) =>
b -> b -> t Char -> b
steps Integer
16 Integer
frontNum String
back
                 exp1 :: Int
exp1    = -Int
4 forall a. Num a => a -> a -> a
* forall (t :: * -> *) a. Foldable t => t a -> Int
length String
back
             case String
rest4 of
               Char
p : String
ps | Char -> Bool
isExp Char
p -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Integer -> Int -> (Integer, Integer)
mk Integer
backNum forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Num a => a -> a -> a
+ Int
exp1)) (forall {a}. Num a => String -> Maybe a
getExp String
ps)
               String
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return (Integer -> Int -> (Integer, Integer)
mk Integer
backNum Int
exp1)
       Char
p : String
ps | Char -> Bool
isExp Char
p -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Integer -> Int -> (Integer, Integer)
mk Integer
frontNum) (forall {a}. Num a => String -> Maybe a
getExp String
ps)
       String
_ -> forall a. Maybe a
Nothing

  where
  isExp :: Char -> Bool
isExp Char
p = Char
p forall a. Eq a => a -> a -> Bool
== Char
'p' Bool -> Bool -> Bool
|| Char
p forall a. Eq a => a -> a -> Bool
== Char
'P'

  getExp :: String -> Maybe a
getExp (Char
'+' : String
ds) = forall {a}. Num a => String -> Maybe a
dec String
ds
  getExp (Char
'-' : String
ds) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Num a => a -> a
negate (forall {a}. Num a => String -> Maybe a
dec String
ds)
  getExp String
ds         = forall {a}. Num a => String -> Maybe a
dec String
ds

  mk :: Integer -> Int -> (Integer, Integer)
  mk :: Integer -> Int -> (Integer, Integer)
mk Integer
n Int
e = (Integer
n, forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
e)

  dec :: String -> Maybe a
dec String
cs = case (Char -> Bool) -> String -> (String, String)
span' Char -> Bool
isDigit String
cs of
             (String
ds,String
"") | Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
ds) -> forall a. a -> Maybe a
Just (forall {t :: * -> *} {b}.
(Foldable t, Num b) =>
b -> b -> t Char -> b
steps a
10 a
0 String
ds)
             (String, String)
_ -> forall a. Maybe a
Nothing

  steps :: b -> b -> t Char -> b
steps b
base b
n t Char
ds = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (forall {a}. Num a => a -> a -> Char -> a
step b
base) b
n t Char
ds
  step :: a -> a -> Char -> a
step  a
base a
n Char
d  = a
base forall a. Num a => a -> a -> a
* a
n forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral (Char -> Int
digitToInt Char
d)

  span' :: (Char -> Bool) -> String -> (String, String)
span' Char -> Bool
_ xs :: String
xs@[]         =  (String
xs, String
xs)
  span' Char -> Bool
p xs :: String
xs@(Char
x:String
xs')
            | Char
x forall a. Eq a => a -> a -> Bool
== Char
'_'  = (Char -> Bool) -> String -> (String, String)
span' Char -> Bool
p String
xs'   -- skip "_"  (#14473)
            | Char -> Bool
p Char
x       =  let (String
ys,String
zs) = (Char -> Bool) -> String -> (String, String)
span' Char -> Bool
p String
xs' in (Char
xforall a. a -> [a] -> [a]
:String
ys,String
zs)
            | Bool
otherwise =  ([],String
xs)

readHexSignificandExponentPair__ String
_ = forall a. Maybe a
Nothing


-----------------------------------------------------------------------------
-- Verify that the 'dirname' portion of a FilePath exists.
--
doesDirNameExist :: FilePath -> IO Bool
doesDirNameExist :: String -> IO Bool
doesDirNameExist String
fpath = String -> IO Bool
doesDirectoryExist (String -> String
takeDirectory String
fpath)

-----------------------------------------------------------------------------
-- Backwards compatibility definition of getModificationTime

getModificationUTCTime :: FilePath -> IO UTCTime
getModificationUTCTime :: String -> IO UTCTime
getModificationUTCTime = String -> IO UTCTime
getModificationTime

-- --------------------------------------------------------------
-- check existence & modification time at the same time

modificationTimeIfExists :: FilePath -> IO (Maybe UTCTime)
modificationTimeIfExists :: String -> IO (Maybe UTCTime)
modificationTimeIfExists String
f =
  (do UTCTime
t <- String -> IO UTCTime
getModificationUTCTime String
f; forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just UTCTime
t))
        forall a. IO a -> (IOException -> IO a) -> IO a
`catchIO` \IOException
e -> if IOException -> Bool
isDoesNotExistError IOException
e
                        then forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
                        else forall a. IOException -> IO a
ioError IOException
e

-- --------------------------------------------------------------
-- atomic file writing by writing to a temporary file first (see #14533)
--
-- This should be used in all cases where GHC writes files to disk
-- and uses their modification time to skip work later,
-- as otherwise a partially written file (e.g. due to crash or Ctrl+C)
-- also results in a skip.

withAtomicRename :: (MonadIO m) => FilePath -> (FilePath -> m a) -> m a
withAtomicRename :: forall (m :: * -> *) a.
MonadIO m =>
String -> (String -> m a) -> m a
withAtomicRename String
targetFile String -> m a
f = do
  -- The temp file must be on the same file system (mount) as the target file
  -- to result in an atomic move on most platforms.
  -- The standard way to ensure that is to place it into the same directory.
  -- This can still be fooled when somebody mounts a different file system
  -- at just the right time, but that is not a case we aim to cover here.
  let temp :: String
temp = String
targetFile String -> String -> String
<.> String
"tmp"
  a
res <- String -> m a
f String
temp
  forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ String -> String -> IO ()
renameFile String
temp String
targetFile
  forall (m :: * -> *) a. Monad m => a -> m a
return a
res

-- --------------------------------------------------------------
-- split a string at the last character where 'pred' is True,
-- returning a pair of strings. The first component holds the string
-- up (but not including) the last character for which 'pred' returned
-- True, the second whatever comes after (but also not including the
-- last character).
--
-- If 'pred' returns False for all characters in the string, the original
-- string is returned in the first component (and the second one is just
-- empty).
splitLongestPrefix :: String -> (Char -> Bool) -> (String,String)
splitLongestPrefix :: String -> (Char -> Bool) -> (String, String)
splitLongestPrefix String
str Char -> Bool
pred
  | forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
r_pre = (String
str,           [])
  | Bool
otherwise  = (forall a. [a] -> [a]
reverse (forall a. [a] -> [a]
tail String
r_pre), forall a. [a] -> [a]
reverse String
r_suf)
                           -- 'tail' drops the char satisfying 'pred'
  where (String
r_suf, String
r_pre) = forall a. (a -> Bool) -> [a] -> ([a], [a])
break Char -> Bool
pred (forall a. [a] -> [a]
reverse String
str)

escapeSpaces :: String -> String
escapeSpaces :: String -> String
escapeSpaces = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\Char
c String
s -> if Char -> Bool
isSpace Char
c then Char
'\\'forall a. a -> [a] -> [a]
:Char
cforall a. a -> [a] -> [a]
:String
s else Char
cforall a. a -> [a] -> [a]
:String
s) String
""

type Suffix = String

--------------------------------------------------------------
-- * Search path
--------------------------------------------------------------

data Direction = Forwards | Backwards

reslash :: Direction -> FilePath -> FilePath
reslash :: Direction -> String -> String
reslash Direction
d = String -> String
f
    where f :: String -> String
f (Char
'/'  : String
xs) = Char
slash forall a. a -> [a] -> [a]
: String -> String
f String
xs
          f (Char
'\\' : String
xs) = Char
slash forall a. a -> [a] -> [a]
: String -> String
f String
xs
          f (Char
x    : String
xs) = Char
x     forall a. a -> [a] -> [a]
: String -> String
f String
xs
          f String
""          = String
""
          slash :: Char
slash = case Direction
d of
                  Direction
Forwards -> Char
'/'
                  Direction
Backwards -> Char
'\\'

makeRelativeTo :: FilePath -> FilePath -> FilePath
String
this makeRelativeTo :: String -> String -> String
`makeRelativeTo` String
that = String
directory String -> String -> String
</> String
thisFilename
    where (String
thisDirectory, String
thisFilename) = String -> (String, String)
splitFileName String
this
          thatDirectory :: String
thatDirectory = String -> String
dropFileName String
that
          directory :: String
directory = [String] -> String
joinPath forall a b. (a -> b) -> a -> b
$ [String] -> [String] -> [String]
f (String -> [String]
splitPath String
thisDirectory)
                                   (String -> [String]
splitPath String
thatDirectory)

          f :: [String] -> [String] -> [String]
f (String
x : [String]
xs) (String
y : [String]
ys)
           | String
x forall a. Eq a => a -> a -> Bool
== String
y = [String] -> [String] -> [String]
f [String]
xs [String]
ys
          f [String]
xs [String]
ys = forall a. Int -> a -> [a]
replicate (forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
ys) String
".." forall a. [a] -> [a] -> [a]
++ [String]
xs

{-
************************************************************************
*                                                                      *
\subsection[Utils-Data]{Utils for defining Data instances}
*                                                                      *
************************************************************************

These functions helps us to define Data instances for abstract types.
-}

abstractConstr :: String -> Constr
abstractConstr :: String -> Constr
abstractConstr String
n = DataType -> String -> [String] -> Fixity -> Constr
mkConstr (String -> DataType
abstractDataType String
n) (String
"{abstract:"forall a. [a] -> [a] -> [a]
++String
nforall a. [a] -> [a] -> [a]
++String
"}") [] Fixity
Prefix

abstractDataType :: String -> DataType
abstractDataType :: String -> DataType
abstractDataType String
n = String -> [Constr] -> DataType
mkDataType String
n [String -> Constr
abstractConstr String
n]

{-
************************************************************************
*                                                                      *
\subsection[Utils-C]{Utils for printing C code}
*                                                                      *
************************************************************************
-}

charToC :: Word8 -> String
charToC :: Word8 -> String
charToC Word8
w =
  case Int -> Char
chr (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
w) of
        Char
'\"' -> String
"\\\""
        Char
'\'' -> String
"\\\'"
        Char
'\\' -> String
"\\\\"
        Char
c | Char
c forall a. Ord a => a -> a -> Bool
>= Char
' ' Bool -> Bool -> Bool
&& Char
c forall a. Ord a => a -> a -> Bool
<= Char
'~' -> [Char
c]
          | Bool
otherwise -> [Char
'\\',
                         Int -> Char
chr (Char -> Int
ord Char
'0' forall a. Num a => a -> a -> a
+ Char -> Int
ord Char
c forall a. Integral a => a -> a -> a
`div` Int
64),
                         Int -> Char
chr (Char -> Int
ord Char
'0' forall a. Num a => a -> a -> a
+ Char -> Int
ord Char
c forall a. Integral a => a -> a -> a
`div` Int
8 forall a. Integral a => a -> a -> a
`mod` Int
8),
                         Int -> Char
chr (Char -> Int
ord Char
'0' forall a. Num a => a -> a -> a
+ Char -> Int
ord Char
c         forall a. Integral a => a -> a -> a
`mod` Int
8)]

{-
************************************************************************
*                                                                      *
\subsection[Utils-Hashing]{Utils for hashing}
*                                                                      *
************************************************************************
-}

-- | A sample hash function for Strings.  We keep multiplying by the
-- golden ratio and adding.  The implementation is:
--
-- > hashString = foldl' f golden
-- >   where f m c = fromIntegral (ord c) * magic + hashInt32 m
-- >         magic = 0xdeadbeef
--
-- Where hashInt32 works just as hashInt shown above.
--
-- Knuth argues that repeated multiplication by the golden ratio
-- will minimize gaps in the hash space, and thus it's a good choice
-- for combining together multiple keys to form one.
--
-- Here we know that individual characters c are often small, and this
-- produces frequent collisions if we use ord c alone.  A
-- particular problem are the shorter low ASCII and ISO-8859-1
-- character strings.  We pre-multiply by a magic twiddle factor to
-- obtain a good distribution.  In fact, given the following test:
--
-- > testp :: Int32 -> Int
-- > testp k = (n - ) . length . group . sort . map hs . take n $ ls
-- >   where ls = [] : [c : l | l <- ls, c <- ['\0'..'\xff']]
-- >         hs = foldl' f golden
-- >         f m c = fromIntegral (ord c) * k + hashInt32 m
-- >         n = 100000
--
-- We discover that testp magic = 0.
hashString :: String -> Int32
hashString :: String -> Int32
hashString = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Int32 -> Char -> Int32
f Int32
golden
   where f :: Int32 -> Char -> Int32
f Int32
m Char
c = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Char -> Int
ord Char
c) forall a. Num a => a -> a -> a
* Int32
magic forall a. Num a => a -> a -> a
+ Int32 -> Int32
hashInt32 Int32
m
         magic :: Int32
magic = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32
0xdeadbeef :: Word32)

golden :: Int32
golden :: Int32
golden = Int32
1013904242 -- = round ((sqrt 5 - 1) * 2^32) :: Int32
-- was -1640531527 = round ((sqrt 5 - 1) * 2^31) :: Int32
-- but that has bad mulHi properties (even adding 2^32 to get its inverse)
-- Whereas the above works well and contains no hash duplications for
-- [-32767..65536]

-- | A sample (and useful) hash function for Int32,
-- implemented by extracting the uppermost 32 bits of the 64-bit
-- result of multiplying by a 33-bit constant.  The constant is from
-- Knuth, derived from the golden ratio:
--
-- > golden = round ((sqrt 5 - 1) * 2^32)
--
-- We get good key uniqueness on small inputs
-- (a problem with previous versions):
--  (length $ group $ sort $ map hashInt32 [-32767..65536]) == 65536 + 32768
--
hashInt32 :: Int32 -> Int32
hashInt32 :: Int32 -> Int32
hashInt32 Int32
x = Int32 -> Int32 -> Int32
mulHi Int32
x Int32
golden forall a. Num a => a -> a -> a
+ Int32
x

-- hi 32 bits of a x-bit * 32 bit -> 64-bit multiply
mulHi :: Int32 -> Int32 -> Int32
mulHi :: Int32 -> Int32 -> Int32
mulHi Int32
a Int32
b = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64
r forall a. Bits a => a -> Int -> a
`shiftR` Int
32)
   where r :: Int64
         r :: Int64
r = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
a forall a. Num a => a -> a -> a
* forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
b

-- | A call stack constraint, but only when 'isDebugOn'.
#if defined(DEBUG)
type HasDebugCallStack = HasCallStack
#else
type HasDebugCallStack = (() :: Constraint)
#endif

data OverridingBool
  = Auto
  | Always
  | Never
  deriving Int -> OverridingBool -> String -> String
[OverridingBool] -> String -> String
OverridingBool -> String
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [OverridingBool] -> String -> String
$cshowList :: [OverridingBool] -> String -> String
show :: OverridingBool -> String
$cshow :: OverridingBool -> String
showsPrec :: Int -> OverridingBool -> String -> String
$cshowsPrec :: Int -> OverridingBool -> String -> String
Show

overrideWith :: Bool -> OverridingBool -> Bool
overrideWith :: Bool -> OverridingBool -> Bool
overrideWith Bool
b OverridingBool
Auto   = Bool
b
overrideWith Bool
_ OverridingBool
Always = Bool
True
overrideWith Bool
_ OverridingBool
Never  = Bool
False