From a269b60282633e3468de85d1882e275507ec0755 Mon Sep 17 00:00:00 2001 From: Julian Ospald Date: Sun, 29 Aug 2021 19:45:26 +0200 Subject: [PATCH] Remove extra --- ghcup.cabal | 1 - lib/GHCup.hs | 1 - lib/GHCup/Download.hs | 3 +- lib/GHCup/Utils.hs | 1 - lib/GHCup/Utils/File/Common.hs | 1 - lib/GHCup/Utils/Prelude.hs | 119 ++++++++++++++++++++++++++++++++- 6 files changed, 120 insertions(+), 6 deletions(-) diff --git a/ghcup.cabal b/ghcup.cabal index c6ba0ed..432c8f0 100644 --- a/ghcup.cabal +++ b/ghcup.cabal @@ -104,7 +104,6 @@ library , deepseq ^>=1.4.4.0 , directory ^>=1.3.6.0 , disk-free-space ^>=0.1.0.1 - , extra ^>=1.7.9 , filepath ^>=1.4.2.1 , haskus-utils-types ^>=1.5 , haskus-utils-variant >=3.0 && <3.2 diff --git a/lib/GHCup.hs b/lib/GHCup.hs index 0489714..4df6afb 100644 --- a/lib/GHCup.hs +++ b/lib/GHCup.hs @@ -58,7 +58,6 @@ import Control.Monad.IO.Unlift ( MonadUnliftIO( withRunInIO ) ) import Data.ByteString ( ByteString ) import Data.Either import Data.List -import Data.List.Extra import Data.Maybe import Data.String ( fromString ) import Data.Text ( Text ) diff --git a/lib/GHCup/Download.hs b/lib/GHCup/Download.hs index b26c949..d72b7f7 100644 --- a/lib/GHCup/Download.hs +++ b/lib/GHCup/Download.hs @@ -57,8 +57,8 @@ import Data.ByteString ( ByteString ) #if defined(INTERNAL_DOWNLOADER) import Data.CaseInsensitive ( mk ) #endif -import Data.List.Extra import Data.Maybe +import Data.List import Data.Time.Clock import Data.Time.Clock.POSIX import Data.Versions @@ -72,6 +72,7 @@ import Prelude hiding ( abs , readFile , writeFile ) +import Safe import System.Directory import System.Environment import System.Exit diff --git a/lib/GHCup/Utils.hs b/lib/GHCup/Utils.hs index 9717cbf..f911224 100644 --- a/lib/GHCup/Utils.hs +++ b/lib/GHCup/Utils.hs @@ -58,7 +58,6 @@ import Data.ByteString ( ByteString ) import Data.Either import Data.Foldable import Data.List -import Data.List.Extra import Data.List.NonEmpty ( NonEmpty( (:|) )) import Data.Maybe import Data.Text ( Text ) diff --git a/lib/GHCup/Utils/File/Common.hs b/lib/GHCup/Utils/File/Common.hs index ca60ea3..3aac1ea 100644 --- a/lib/GHCup/Utils/File/Common.hs +++ b/lib/GHCup/Utils/File/Common.hs @@ -7,7 +7,6 @@ module GHCup.Utils.File.Common where import GHCup.Utils.Prelude -import Control.Monad.Extra import Control.Monad.Reader import Data.Maybe import GHC.IO.Exception diff --git a/lib/GHCup/Utils/Prelude.hs b/lib/GHCup/Utils/Prelude.hs index 22f758d..dc0601e 100644 --- a/lib/GHCup/Utils/Prelude.hs +++ b/lib/GHCup/Utils/Prelude.hs @@ -33,7 +33,8 @@ import Control.Monad.Reader import Control.Monad.Logger import Data.Bifunctor import Data.ByteString ( ByteString ) -import Data.List ( nub, intercalate ) +import Data.List ( nub, intercalate, stripPrefix, isPrefixOf ) +import Data.Maybe import Data.Foldable import Data.String import Data.Text ( Text ) @@ -76,6 +77,8 @@ import qualified System.Win32.File as Win32 -- >>> import Test.QuickCheck -- >>> import Data.Word8 -- >>> import qualified Data.Text as T +-- >>> import qualified Data.Char as C +-- >>> import Data.List -- >>> instance Arbitrary T.Text where arbitrary = T.pack <$> arbitrary @@ -580,3 +583,117 @@ splitOnPVP c s = case Split.splitOn c s of | otherwise -> def where def = (s, "") + + + +-- | Like 'find', but where the test can be monadic. +-- +-- >>> findM (Just . C.isUpper) "teST" +-- Just (Just 'S') +-- >>> findM (Just . C.isUpper) "test" +-- Just Nothing +-- >>> findM (Just . const True) ["x",undefined] +-- Just (Just "x") +findM :: Monad m => (a -> m Bool) -> [a] -> m (Maybe a) +findM ~p = foldr (\x -> ifM (p x) (pure $ Just x)) (pure Nothing) + + +-- | Drops the given suffix from a list. +-- It returns the original sequence if the sequence doesn't end with the given suffix. +-- +-- >>> dropSuffix "!" "Hello World!" +-- "Hello World" +-- >>> dropSuffix "!" "Hello World!!" +-- "Hello World!" +-- >>> dropSuffix "!" "Hello World." +-- "Hello World." +dropSuffix :: Eq a => [a] -> [a] -> [a] +dropSuffix a b = fromMaybe b $ stripSuffix a b + +-- | Return the prefix of the second list if its suffix +-- matches the entire first list. +-- +-- >>> stripSuffix "bar" "foobar" +-- Just "foo" +-- >>> stripSuffix "" "baz" +-- Just "baz" +-- >>> stripSuffix "foo" "quux" +-- Nothing +stripSuffix :: Eq a => [a] -> [a] -> Maybe [a] +stripSuffix a b = reverse <$> stripPrefix (reverse a) (reverse b) + + +-- | Drops the given prefix from a list. +-- It returns the original sequence if the sequence doesn't start with the given prefix. +-- +-- >>> dropPrefix "Mr. " "Mr. Men" +-- "Men" +-- >>> dropPrefix "Mr. " "Dr. Men" +-- "Dr. Men" +dropPrefix :: Eq a => [a] -> [a] -> [a] +dropPrefix a b = fromMaybe b $ stripPrefix a b + + + +-- | Break a list into pieces separated by the first +-- list argument, consuming the delimiter. An empty delimiter is +-- invalid, and will cause an error to be raised. +-- +-- >>> splitOn "\r\n" "a\r\nb\r\nd\r\ne" +-- ["a","b","d","e"] +-- >>> splitOn "aaa" "aaaXaaaXaaaXaaa" +-- ["","X","X","X",""] +-- >>> splitOn "x" "x" +-- ["",""] +-- >>> splitOn "x" "" +-- [""] +-- +-- prop> \s x -> s /= "" ==> intercalate s (splitOn s x) == x +-- prop> \c x -> splitOn [c] x == split (==c) x +splitOn :: Eq a => [a] -> [a] -> [[a]] +splitOn [] _ = error "splitOn, needle may not be empty" +splitOn _ [] = [[]] +splitOn needle haystack = a : if null b then [] else splitOn needle $ drop (length needle) b + where (a,b) = breakOn needle haystack + + +-- | Splits a list into components delimited by separators, +-- where the predicate returns True for a separator element. The +-- resulting components do not contain the separators. Two adjacent +-- separators result in an empty component in the output. +-- +-- >>> split (== 'a') "aabbaca" +-- ["","","bb","c",""] +-- >>> split (== 'a') "" +-- [""] +-- >>> split (== ':') "::xyz:abc::123::" +-- ["","","xyz","abc","","123","",""] +-- >>> split (== ',') "my,list,here" +-- ["my","list","here"] +split :: (a -> Bool) -> [a] -> [[a]] +split _ [] = [[]] +split f (x:xs) + | f x = [] : split f xs + | y:ys <- split f xs = (x:y) : ys + | otherwise = [[]] + + +-- | Find the first instance of @needle@ in @haystack@. +-- The first element of the returned tuple +-- is the prefix of @haystack@ before @needle@ is matched. The second +-- is the remainder of @haystack@, starting with the match. +-- If you want the remainder /without/ the match, use 'stripInfix'. +-- +-- >>> breakOn "::" "a::b::c" +-- ("a","::b::c") +-- >>> breakOn "/" "foobar" +-- ("foobar","") +-- +-- prop> \needle haystack -> let (prefix,match) = breakOn needle haystack in prefix ++ match == haystack +breakOn :: Eq a => [a] -> [a] -> ([a], [a]) +breakOn needle haystack | needle `isPrefixOf` haystack = ([], haystack) +breakOn _ [] = ([], []) +breakOn needle (x:xs) = first (x:) $ breakOn needle xs + + +