packages feed

extra 1.6.14 → 1.6.15

raw patch · 20 files changed

+167/−354 lines, 20 filesdep +semigroupsdep ~basePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: semigroups

Dependency ranges changed: base

API changes (from Hackage documentation)

- Control.Concurrent.Extra: forkFinally :: () => IO a -> (Either SomeException a -> IO ()) -> IO ThreadId
- Control.Concurrent.Extra: getNumCapabilities :: IO Int
- Control.Concurrent.Extra: setNumCapabilities :: Int -> IO ()
- Control.Exception.Extra: displayException :: Exception e => e -> String
- Data.Either.Extra: isLeft :: () => Either a b -> Bool
- Data.Either.Extra: isRight :: () => Either a b -> Bool
- Data.IORef.Extra: atomicModifyIORef' :: () => IORef a -> (a -> (a, b)) -> IO b
- Data.IORef.Extra: atomicWriteIORef :: () => IORef a -> a -> IO ()
- Data.IORef.Extra: modifyIORef' :: () => IORef a -> (a -> a) -> IO ()
- Data.List.Extra: dropWhileEnd :: () => (a -> Bool) -> [a] -> [a]
- Data.List.Extra: sortOn :: Ord b => (a -> b) -> [a] -> [a]
- Data.List.Extra: uncons :: () => [a] -> Maybe (a, [a])
- Data.Typeable.Extra: Proxy :: Proxy
- Data.Typeable.Extra: [Refl] :: forall k (a :: k) (b :: k). () => a :~: a
- Data.Typeable.Extra: data Proxy (t :: k) :: forall k. () => k -> Type
- Data.Typeable.Extra: infix 4 :~:
- Data.Typeable.Extra: typeRep :: Typeable a => proxy a -> TypeRep
- Data.Version.Extra: makeVersion :: [Int] -> Version
- Extra: Proxy :: Proxy
- Extra: [Refl] :: forall k (a :: k) (b :: k). () => a :~: a
- Extra: atomicModifyIORef' :: () => IORef a -> (a -> (a, b)) -> IO b
- Extra: atomicWriteIORef :: () => IORef a -> a -> IO ()
- Extra: data Proxy (t :: k) :: forall k. () => k -> Type
- Extra: displayException :: Exception e => e -> String
- Extra: dropWhileEnd :: () => (a -> Bool) -> [a] -> [a]
- Extra: forkFinally :: () => IO a -> (Either SomeException a -> IO ()) -> IO ThreadId
- Extra: getExecutablePath :: IO FilePath
- Extra: getNumCapabilities :: IO Int
- Extra: infix 4 :~:
- Extra: isLeft :: () => Either a b -> Bool
- Extra: isRight :: () => Either a b -> Bool
- Extra: lookupEnv :: String -> IO (Maybe String)
- Extra: makeVersion :: [Int] -> Version
- Extra: modifyIORef' :: () => IORef a -> (a -> a) -> IO ()
- Extra: readEither :: Read a => String -> Either String a
- Extra: readMaybe :: Read a => String -> Maybe a
- Extra: setNumCapabilities :: Int -> IO ()
- Extra: sortOn :: Ord b => (a -> b) -> [a] -> [a]
- Extra: typeRep :: Typeable a => proxy a -> TypeRep
- Extra: uncons :: () => [a] -> Maybe (a, [a])
- System.Environment.Extra: getExecutablePath :: IO FilePath
- System.Environment.Extra: lookupEnv :: String -> IO (Maybe String)
- Text.Read.Extra: readEither :: Read a => String -> Either String a
- Text.Read.Extra: readMaybe :: Read a => String -> Maybe a
+ Control.Monad.Extra: fromMaybeM :: Monad m => m a -> m (Maybe a) -> m a
+ Data.List.NonEmpty.Extra: (|:) :: [a] -> a -> NonEmpty a
+ Data.List.NonEmpty.Extra: (|>) :: NonEmpty a -> a -> NonEmpty a
+ Data.List.NonEmpty.Extra: appendl :: NonEmpty a -> [a] -> NonEmpty a
+ Data.List.NonEmpty.Extra: appendr :: [a] -> NonEmpty a -> NonEmpty a
+ Data.List.NonEmpty.Extra: infixl 5 |>
+ Data.List.NonEmpty.Extra: maximum1 :: Ord a => NonEmpty a -> a
+ Data.List.NonEmpty.Extra: maximumBy1 :: (a -> a -> Ordering) -> NonEmpty a -> a
+ Data.List.NonEmpty.Extra: maximumOn1 :: Ord b => (a -> b) -> NonEmpty a -> a
+ Data.List.NonEmpty.Extra: minimum1 :: Ord a => NonEmpty a -> a
+ Data.List.NonEmpty.Extra: minimumBy1 :: (a -> a -> Ordering) -> NonEmpty a -> a
+ Data.List.NonEmpty.Extra: minimumOn1 :: Ord b => (a -> b) -> NonEmpty a -> a
+ Data.List.NonEmpty.Extra: snoc :: NonEmpty a -> a -> NonEmpty a
+ Data.List.NonEmpty.Extra: sortOn :: Ord b => (a -> b) -> NonEmpty a -> NonEmpty a
+ Data.List.NonEmpty.Extra: union :: Eq a => NonEmpty a -> NonEmpty a -> NonEmpty a
+ Data.List.NonEmpty.Extra: unionBy :: (a -> a -> Bool) -> NonEmpty a -> NonEmpty a -> NonEmpty a
+ Extra: (|:) :: [a] -> a -> NonEmpty a
+ Extra: (|>) :: NonEmpty a -> a -> NonEmpty a
+ Extra: appendl :: NonEmpty a -> [a] -> NonEmpty a
+ Extra: appendr :: [a] -> NonEmpty a -> NonEmpty a
+ Extra: fromMaybeM :: Monad m => m a -> m (Maybe a) -> m a
+ Extra: infixl 5 |>
+ Extra: maximum1 :: Ord a => NonEmpty a -> a
+ Extra: maximumBy1 :: (a -> a -> Ordering) -> NonEmpty a -> a
+ Extra: maximumOn1 :: Ord b => (a -> b) -> NonEmpty a -> a
+ Extra: minimum1 :: Ord a => NonEmpty a -> a
+ Extra: minimumBy1 :: (a -> a -> Ordering) -> NonEmpty a -> a
+ Extra: minimumOn1 :: Ord b => (a -> b) -> NonEmpty a -> a

Files

CHANGES.txt view
@@ -1,5 +1,9 @@ Changelog for Extra +1.6.15, released 2019-04-22+    #45, add NonEmpty.Extra for extra appending functions+    #42, add fromMaybeM+    Remove support for GHC 7.4, 7.6 and 7.8 1.6.14, released 2018-12-10     Add mapLeft and mapRight 1.6.13, released 2018-10-14
Generate.hs view
@@ -37,11 +37,11 @@         ,"module Extra {-# DEPRECATED \"This module is provided as documentation of all new functions, you should import the more specific modules directly.\" #-} ("] ++         concat [ ["    -- * " ++ mod                  ,"    -- | Extra functions available in @" ++ show mod ++ "@."-                 ,"    " ++ unwords (map (++",") funs)]-               | (mod,funs,_) <- ifaces] +++                 ,"    " ++ unwords (map (++",") $ filter (notHidden mod) funs)]+               | (mod,funs@(_:_),_) <- ifaces] ++         ["    ) where"         ,""] ++-        ["import " ++ x | x <- mods]+        ["import " ++ addHiding mod | (mod,_:_,_) <- ifaces]     writeFileBinaryChanged "test/TestGen.hs" $ unlines $         ["-- GENERATED CODE - DO NOT MODIFY"         ,"-- See Generate.hs for details of how to generate"@@ -66,6 +66,17 @@     when (Just x /= old) $         writeFileBinary file x +hidden :: String -> [String]+hidden "Data.List.NonEmpty.Extra" = ["cons", "snoc", "sortOn", "union", "unionBy"]+hidden _ = []++notHidden :: String -> String -> Bool+notHidden mod fun = fun `notElem` hidden mod++addHiding :: String -> String+addHiding mod+  | xs@(_:_) <- hidden mod = mod ++ " hiding (" ++ intercalate ", " xs ++ ")"+  | otherwise = mod  validIdentifier xs =     (take 1 xs == "(" || isName (takeWhile (/= '(') xs)) &&
LICENSE view
@@ -1,4 +1,4 @@-Copyright Neil Mitchell 2014-2018.+Copyright Neil Mitchell 2014-2019. All rights reserved.  Redistribution and use in source and binary forms, with or without
README.md view
@@ -1,11 +1,11 @@-# Extra [![Hackage version](https://img.shields.io/hackage/v/extra.svg?label=Hackage)](https://hackage.haskell.org/package/extra) [![Stackage version](https://www.stackage.org/package/extra/badge/nightly?label=Stackage)](https://www.stackage.org/package/extra) [![Linux Build Status](https://img.shields.io/travis/ndmitchell/extra/master.svg?label=Linux%20build)](https://travis-ci.org/ndmitchell/extra) [![Windows Build Status](https://img.shields.io/appveyor/ci/ndmitchell/extra/master.svg?label=Windows%20build)](https://ci.appveyor.com/project/ndmitchell/extra)+# Extra [![Hackage version](https://img.shields.io/hackage/v/extra.svg?label=Hackage)](https://hackage.haskell.org/package/extra) [![Stackage version](https://www.stackage.org/package/extra/badge/nightly?label=Stackage)](https://www.stackage.org/package/extra) [![Linux build status](https://img.shields.io/travis/ndmitchell/extra/master.svg?label=Linux%20build)](https://travis-ci.org/ndmitchell/extra) [![Windows build status](https://img.shields.io/appveyor/ci/ndmitchell/extra/master.svg?label=Windows%20build)](https://ci.appveyor.com/project/ndmitchell/extra) -A library of extra functions for the standard Haskell libraries. Most functions are simple additions, filling out missing functionality. A few functions are available in later versions of GHC, but this package makes them available back to GHC 7.2. A few examples:+A library of extra functions for the standard Haskell libraries. Most functions are simple additions, filling out missing functionality. A few functions are available in later versions of GHC, but this package makes them available back to GHC 7.10. A few examples:  * `Control.Monad.Extra.concatMapM` provides a monadic version of `concatMap`, in the same way that `mapM` is a monadic version of `map`. * `Data.Tuple.Extra.fst3` provides a function to get the first element of a triple. * `Control.Exception.Extra.retry` provides a function that retries an `IO` action a number of times.-* `System.Environment.Extra.lookupEnv` is a function available in GHC 7.6 and above. On GHC 7.6 and above this package reexports the version from `System.Environment` while on GHC 7.4 and below it defines an equivalent version.+* `Data.Either.Extra.fromLeft` is a function available in GHC 8.0 and above. On GHC 8.0 and above this package reexports the version from `Data.Either` while on GHC 7.10 and below it defines an equivalent version.  The module `Extra` documents all functions provided by this library. Modules such as `Data.List.Extra` provide extra functions over `Data.List` and also reexport `Data.List`. Users are recommended to replace `Data.List` imports with `Data.List.Extra` if they need the extra functionality. 
extra.cabal view
@@ -1,13 +1,13 @@ cabal-version:      >= 1.18 build-type:         Simple name:               extra-version:            1.6.14+version:            1.6.15 license:            BSD3 license-file:       LICENSE category:           Development author:             Neil Mitchell <ndmitchell@gmail.com> maintainer:         Neil Mitchell <ndmitchell@gmail.com>-copyright:          Neil Mitchell 2014-2018+copyright:          Neil Mitchell 2014-2019 synopsis:           Extra functions I use. description:     A library of extra functions for the standard Haskell libraries. Most functions are simple additions, filling out missing functionality. A few functions are available in later versions of GHC, but this package makes them available back to GHC 7.2.@@ -15,7 +15,7 @@     The module "Extra" documents all functions provided by this library. Modules such as "Data.List.Extra" provide extra functions over "Data.List" and also reexport "Data.List". Users are recommended to replace "Data.List" imports with "Data.List.Extra" if they need the extra functionality. homepage:           https://github.com/ndmitchell/extra#readme bug-reports:        https://github.com/ndmitchell/extra/issues-tested-with:        GHC==8.6.3, GHC==8.4.4, GHC==8.2.2, GHC==8.0.2, GHC==7.10.3, GHC==7.8.4, GHC==7.6.3, GHC==7.4.2+tested-with:        GHC==8.6.4, GHC==8.4.4, GHC==8.2.2, GHC==8.0.2, GHC==7.10.3  extra-doc-files:     CHANGES.txt@@ -31,11 +31,13 @@     default-language: Haskell2010     hs-source-dirs: src     build-depends:-        base >= 4.4 && < 5,+        base >= 4.8 && < 5,         directory,         filepath,         process,         clock >= 0.7,+        -- For GHC 7.10 since Data.List.NonEmpty wasn't in base then+        semigroups,         time     if !os(windows)         build-depends: unix@@ -50,6 +52,7 @@         Data.Either.Extra         Data.IORef.Extra         Data.List.Extra+        Data.List.NonEmpty.Extra         Data.Tuple.Extra         Data.Typeable.Extra         Data.Version.Extra
src/Control/Concurrent/Extra.hs view
@@ -1,5 +1,4 @@-{-# LANGUAGE CPP, TupleSections, ConstraintKinds #-}-{-# OPTIONS_GHC -fno-warn-duplicate-exports #-}+{-# LANGUAGE TupleSections, ConstraintKinds #-}  -- | Extra functions for "Control.Concurrent". --@@ -14,8 +13,8 @@ --   see the <httdp://hackage.haskell.org/package/async async> package. module Control.Concurrent.Extra(     module Control.Concurrent,-    getNumCapabilities, setNumCapabilities, withNumCapabilities,-    forkFinally, once, onceFork,+    withNumCapabilities,+    once, onceFork,     -- * Lock     Lock, newLock, withLock, withLockTry,     -- * Var@@ -41,39 +40,6 @@     if old == new then act else         bracket_ (setNumCapabilities new) (setNumCapabilities old) act withNumCapabilities _ act = act---#if __GLASGOW_HASKELL__ < 702--- | A version of 'getNumCapabilities' that works on all versions of GHC, but returns 1 before GHC 7.2.-getNumCapabilities :: IO Int-getNumCapabilities = return 1-#endif--#if __GLASGOW_HASKELL__ < 706--- | A version of 'setNumCapabilities' that works on all versions of GHC, but has no effect before GHC 7.6.-setNumCapabilities :: Int -> IO ()-setNumCapabilities n = return ()-#endif---#if __GLASGOW_HASKELL__ < 706--- | fork a thread and call the supplied function when the thread is about--- to terminate, with an exception or a returned value.  The function is--- called with asynchronous exceptions masked.------ @--- 'forkFinally' action and_then =---    mask $ \restore ->---      forkIO $ try (restore action) >>= and_then--- @------ This function is useful for informing the parent when a child--- terminates, for example.-forkFinally :: IO a -> (Either SomeException a -> IO ()) -> IO ThreadId-forkFinally action and_then =-  mask $ \restore ->-    forkIO $ try (restore action) >>= and_then-#endif   -- | Given an action, produce a wrapped action that runs at most once.
src/Control/Exception/Extra.hs view
@@ -13,7 +13,7 @@     retry, retryBool,     errorWithoutStackTrace,     showException, stringException,-    errorIO, displayException,+    errorIO,     -- * Exception catching/ignoring     ignore,     catch_, handle_, try_,@@ -51,13 +51,6 @@ showException :: Show e => e -> IO String showException = stringException . show --#if __GLASGOW_HASKELL__ < 710--- | Render this exception value in a human-friendly manner.---   Part of the 'Exception' class in GHC 7.10 onwards.-displayException :: Exception e => e -> String-displayException = show-#endif  #if __GLASGOW_HASKELL__ < 800 -- | A variant of 'error' that does not produce a stack trace.
src/Control/Monad/Extra.hs view
@@ -9,7 +9,7 @@     whenJust, whenJustM,     whenMaybe, whenMaybeM,     unit,-    maybeM, eitherM,+    maybeM, fromMaybeM, eitherM,     -- * Loops     loop, loopM, whileM,     -- * Lists@@ -68,6 +68,11 @@ -- | Monadic generalisation of 'maybe'. maybeM :: Monad m => m b -> (a -> m b) -> m (Maybe a) -> m b maybeM n j x = maybe n j =<< x+++-- | Monadic generalisation of 'fromMaybe'.+fromMaybeM :: Monad m => m a -> m (Maybe a) -> m a+fromMaybeM n x = maybe n pure =<< x   -- | Monadic generalisation of 'either'.
src/Data/Either/Extra.hs view
@@ -9,7 +9,7 @@ --   <https://hackage.haskell.org/package/either either>. module Data.Either.Extra(     module Data.Either,-    isLeft, isRight, fromLeft, fromRight, fromEither,+    fromLeft, fromRight, fromEither,     fromLeft', fromRight',     eitherToMaybe, maybeToEither,     mapLeft, mapRight,@@ -60,18 +60,6 @@ fromRight' (Right x) = x fromRight' _ = error "fromRight', given a Left" --#if __GLASGOW_HASKELL__ < 708--- | Test if an 'Either' value is the 'Left' constructor.---   Provided as standard with GHC 7.8 and above.-isLeft :: Either l r -> Bool-isLeft Left{} = True; isLeft _ = False---- | Test if an 'Either' value is the 'Right' constructor.---   Provided as standard with GHC 7.8 and above.-isRight :: Either l r -> Bool-isRight Right{} = True; isRight _ = False-#endif  -- | Pull the value out of an 'Either' where both alternatives --   have the same type.
src/Data/IORef/Extra.hs view
@@ -1,11 +1,9 @@-{-# LANGUAGE CPP #-}-{-# OPTIONS_GHC -fno-warn-duplicate-exports #-}  -- | This module extends "Data.IORef" with operations forcing the value written to the IORef. --   Some of these functions are available in later versions of GHC, but not all. module Data.IORef.Extra(     module Data.IORef,-    modifyIORef', writeIORef', atomicModifyIORef', atomicWriteIORef, atomicWriteIORef'+    writeIORef', atomicWriteIORef'     ) where  import Data.IORef@@ -23,30 +21,3 @@ atomicWriteIORef' ref x = do     evaluate x     atomicWriteIORef ref x---#if __GLASGOW_HASKELL__ < 706---- | Version of 'modifyIORef' that evaluates the function.-modifyIORef' :: IORef a -> (a -> a) -> IO ()-modifyIORef' ref f = do-    x <- readIORef ref-    writeIORef' ref $ f x---- | Strict version of 'atomicModifyIORef'.  This forces both the value stored--- in the 'IORef' as well as the value returned.-atomicModifyIORef' :: IORef a -> (a -> (a,b)) -> IO b-atomicModifyIORef' ref f = do-    b <- atomicModifyIORef ref-            (\x -> let (a, b) = f x-                    in (a, a `seq` b))-    b `seq` return b---- | Variant of 'writeIORef' with the \"barrier to reordering\" property that--- 'atomicModifyIORef' has.-atomicWriteIORef :: IORef a -> a -> IO ()-atomicWriteIORef ref a = do-    x <- atomicModifyIORef ref $ const (a, ())-    x `seq` return ()--#endif
src/Data/List/Extra.hs view
@@ -1,5 +1,4 @@-{-# LANGUAGE CPP, TupleSections, BangPatterns, ConstraintKinds #-}-{-# OPTIONS_GHC -fno-warn-duplicate-exports #-}+{-# LANGUAGE TupleSections, BangPatterns, ConstraintKinds #-}  -- | This module extends "Data.List" with extra functions of a similar nature. --   The package also exports the existing "Data.List" functions.@@ -13,17 +12,17 @@     unescapeHTML, unescapeJSON,     -- * Splitting     dropEnd, takeEnd, splitAtEnd, breakEnd, spanEnd,-    dropWhileEnd, dropWhileEnd', takeWhileEnd,+    dropWhileEnd', takeWhileEnd,     stripSuffix, stripInfix, stripInfixEnd,     dropPrefix, dropSuffix,     wordsBy, linesBy,     breakOn, breakOnEnd, splitOn, split, chunksOf,     -- * Basics-    notNull, list, uncons, unsnoc, cons, snoc, drop1, mconcatMap,+    notNull, list, unsnoc, cons, snoc, drop1, mconcatMap,     -- * List operations     groupSort, groupSortOn, groupSortBy,     nubOrd, nubOrdBy, nubOrdOn,-    nubOn, groupOn, sortOn,+    nubOn, groupOn,     nubSort, nubSortBy, nubSortOn,     maximumOn, minimumOn,     disjoint, allSame, anySame,@@ -114,17 +113,6 @@ list nil cons [] = nil list nil cons (x:xs) = cons x xs -#if __GLASGOW_HASKELL__ < 709--- | If the list is empty returns 'Nothing', otherwise returns the 'head' and the 'tail'.------ > uncons "test" == Just ('t',"est")--- > uncons ""     == Nothing--- > \xs -> uncons xs == if null xs then Nothing else Just (head xs, tail xs)-uncons :: [a] -> Maybe (a, [a])-uncons [] = Nothing-uncons (x:xs) = Just (x,xs)-#endif- -- | If the list is empty returns 'Nothing', otherwise returns the 'init' and the 'last'. -- -- > unsnoc "test" == Just ("tes",'t')@@ -353,18 +341,6 @@ unescapeJSON [] = []  -#if __GLASGOW_HASKELL__ < 709--- | Sort a list by comparing the results of a key function applied to each--- element.  @sortOn f@ is equivalent to @sortBy (comparing f)@, but has the--- performance advantage of only evaluating @f@ once for each element in the--- input list.  This is called the decorate-sort-undecorate paradigm, or--- Schwartzian transform.------ > sortOn fst [(3,"z"),(1,""),(3,"a")] == [(1,""),(3,"z"),(3,"a")]-sortOn :: Ord b => (a -> b) -> [a] -> [a]-sortOn f = map snd . sortBy (compare `on` fst) . map (\x -> let y = f x in y `seq` (y, x))-#endif- -- | A version of 'group' where the equality is done on some extracted value. groupOn :: Eq b => (a -> b) -> [a] -> [[a]] groupOn f = groupBy ((==) `on2` f)@@ -569,12 +545,6 @@ split f [] = [[]] split f (x:xs) | f x = [] : split f xs split f (x:xs) | y:ys <- split f xs = (x:y) : ys---#if __GLASGOW_HASKELL__ < 704-dropWhileEnd :: (a -> Bool) -> [a] -> [a]-dropWhileEnd p = foldr (\x xs -> if p x && null xs then [] else x : xs) []-#endif   -- | A version of 'dropWhileEnd' but with different strictness properties.
+ src/Data/List/NonEmpty/Extra.hs view
@@ -0,0 +1,93 @@+{-# LANGUAGE CPP #-}++-- | Extra functions for working with 'NonEmpty' lists. The package+--   also exports the existing "Data.List.NonEmpty" functions.+module Data.List.NonEmpty.Extra(+    module Data.List.NonEmpty,+    (|:), (|>), snoc,+    appendl, appendr,+    sortOn, union, unionBy,+    maximum1, minimum1, maximumBy1, minimumBy1, maximumOn1, minimumOn1+    ) where++import           Data.Function+import qualified Data.List as List+import           Data.List.NonEmpty++#if __GLASGOW_HASKELL__ <= 802+import Data.Semigroup ((<>))+#endif++infixl 5 |>, |:++-- | /O(n)/. Append an element to a non-empty list.+--+-- > (1 :| [2,3]) |> 4 |> 5 == 1 :| [2,3,4,5]+(|>) :: NonEmpty a -> a -> NonEmpty a+(|>) xs x = xs <> pure x++-- | Synonym for '|>'.+snoc :: NonEmpty a -> a -> NonEmpty a+snoc = (|>)++-- | /O(n)/. Append an element to a list.+--+-- > [1,2,3] |: 4 |> 5 == 1 :| [2,3,4,5]+(|:) :: [a] -> a -> NonEmpty a+(|:) xs x = foldr cons (pure x) xs++-- | Append a list to a non-empty list.+--+-- > appendl (1 :| [2,3]) [4,5] == 1 :| [2,3,4,5]+appendl :: NonEmpty a -> [a] -> NonEmpty a+appendl (x :| xs) l = x :| (xs ++ l)++-- | Append a non-empty list to a list.+--+-- > appendr [1,2,3] (4 :| [5]) == 1 :| [2,3,4,5]+appendr :: [a] -> NonEmpty a -> NonEmpty a+appendr l nel = foldr cons nel l++-- | Sort by comparing the results of a function applied to each element.+--   The sort is stable, and the function is evaluated only once for+--   each element.+sortOn :: Ord b => (a -> b) -> NonEmpty a -> NonEmpty a+sortOn f = fromList . List.sortOn f . toList++-- | Return the union of two non-empty lists. Duplicates, and elements of the+--   first list, are removed from the the second list, but if the first list+--   contains duplicates, so will the result.+--+-- > (1 :| [3, 5, 3]) `union` (4 :| [5, 3, 5, 2]) == 1 :| [3, 5, 3, 4, 2]+union :: Eq a => NonEmpty a -> NonEmpty a -> NonEmpty a+union = unionBy (==)++-- | The non-overloaded version of 'union'.+unionBy :: (a -> a -> Bool) -> NonEmpty a -> NonEmpty a -> NonEmpty a+unionBy eq xs ys = fromList $ List.unionBy eq (toList xs) (toList ys)++-- | The largest element of a non-empty list.+maximum1 :: Ord a => NonEmpty a -> a+maximum1 = List.maximum++-- | The least element of a non-empty list.+minimum1 :: Ord a => NonEmpty a -> a+minimum1 = List.minimum++-- | The largest element of a non-empty list with respect to the given+--   comparison function.+maximumBy1 :: (a -> a -> Ordering) -> NonEmpty a -> a+maximumBy1 = List.maximumBy++-- | The least element of a non-empty list with respect to the given+--   comparison function.+minimumBy1 :: (a -> a -> Ordering) -> NonEmpty a -> a+minimumBy1 = List.minimumBy++-- | A version of 'maximum1' where the comparison is done on some extracted value.+maximumOn1 :: Ord b => (a -> b) -> NonEmpty a -> a+maximumOn1 f = maximumBy1 (compare `on` f)++-- | A version of 'minimum1' where the comparison is done on some extracted value.+minimumOn1 :: Ord b => (a -> b) -> NonEmpty a -> a+minimumOn1 f = minimumBy1 (compare `on` f)
src/Data/Typeable/Extra.hs view
@@ -1,129 +1,10 @@-{-# LANGUAGE CPP, ScopedTypeVariables, TypeOperators, GADTs, StandaloneDeriving #-}-{-# OPTIONS_GHC -fno-warn-duplicate-exports #-}  -- | This module extends "Data.Typeable" with extra functions available in later GHC versions. --   The package also exports the existing "Data.Typeable" functions.+--+--   Currently this module has no functionality beyond "Data.Typeable". module Data.Typeable.Extra(-    typeRep, (:~:)(..), Proxy(..),     module Data.Typeable     ) where  import Data.Typeable--#if __GLASGOW_HASKELL__ < 708--import Data.Ix-import Data.Monoid-import Control.Monad-import Control.Applicative----- | Takes a value of type @a@ and returns a concrete representation---   of that type.------ > typeRep (Proxy :: Proxy Int) == typeOf (1 :: Int)-typeRep :: forall proxy a. Typeable a => proxy a -> TypeRep-typeRep _ = typeOf (undefined :: a)---infix 4 :~:---- | Propositional equality. If @a :~: b@ is inhabited by some terminating--- value, then the type @a@ is the same as the type @b@. To use this equality--- in practice, pattern-match on the @a :~: b@ to get out the @Refl@ constructor;--- in the body of the pattern-match, the compiler knows that @a ~ b@.-data a :~: b where-    Refl :: a :~: a--deriving instance Eq   (a :~: b)-deriving instance Show (a :~: b)-deriving instance Ord  (a :~: b)--instance a ~ b => Read (a :~: b) where-  readsPrec d = readParen (d > 10) (\r -> [(Refl, s) | ("Refl",s) <- lex r ])--instance a ~ b => Enum (a :~: b) where-  toEnum 0 = Refl-  toEnum _ = errorWithoutStackTrace "Data.Type.Equality.toEnum: bad argument"--  fromEnum Refl = 0--instance a ~ b => Bounded (a :~: b) where-  minBound = Refl-  maxBound = Refl------ | A canonical proxy type-data Proxy t = Proxy---- It's common to use (undefined :: Proxy t) and (Proxy :: Proxy t)--- interchangeably, so all of these instances are hand-written to be--- lazy in Proxy arguments.--instance Eq (Proxy s) where-  _ == _ = True--instance Ord (Proxy s) where-  compare _ _ = EQ--instance Show (Proxy s) where-  showsPrec _ _ = showString "Proxy"--instance Read (Proxy s) where-  readsPrec d = readParen (d > 10) (\r -> [(Proxy, s) | ("Proxy",s) <- lex r ])--errorWithoutStackTrace = error--instance Enum (Proxy s) where-    succ _               = errorWithoutStackTrace "Proxy.succ"-    pred _               = errorWithoutStackTrace "Proxy.pred"-    fromEnum _           = 0-    toEnum 0             = Proxy-    toEnum _             = errorWithoutStackTrace "Proxy.toEnum: 0 expected"-    enumFrom _           = [Proxy]-    enumFromThen _ _     = [Proxy]-    enumFromThenTo _ _ _ = [Proxy]-    enumFromTo _ _       = [Proxy]--instance Ix (Proxy s) where-    range _           = [Proxy]-    index _ _         = 0-    inRange _ _       = True-    rangeSize _       = 1--instance Bounded (Proxy s) where-    minBound = Proxy-    maxBound = Proxy--instance Monoid (Proxy s) where-    mempty = Proxy-    mappend _ _ = Proxy-    mconcat _ = Proxy--instance Functor Proxy where-    fmap _ _ = Proxy-    {-# INLINE fmap #-}--instance Applicative Proxy where-    pure _ = Proxy-    {-# INLINE pure #-}-    _ <*> _ = Proxy-    {-# INLINE (<*>) #-}--instance Alternative Proxy where-    empty = Proxy-    {-# INLINE empty #-}-    _ <|> _ = Proxy-    {-# INLINE (<|>) #-}--instance Monad Proxy where-    return = pure-    _ >>= _ = Proxy-    {-# INLINE (>>=) #-}--instance MonadPlus Proxy where-    mzero = empty-    mplus = (<|>)--#endif
src/Data/Version/Extra.hs view
@@ -1,11 +1,10 @@-{-# LANGUAGE CPP, ConstraintKinds #-}-{-# OPTIONS_GHC -fno-warn-duplicate-exports #-}+{-# LANGUAGE ConstraintKinds #-}  -- | This module extends "Data.Version" with extra utilities. --   The package also exports the existing "Data.Version" functions. module Data.Version.Extra(     module Data.Version,-    makeVersion, readVersion+    readVersion     ) where  import Partial@@ -13,16 +12,6 @@ import Data.List.Extra import Text.ParserCombinators.ReadP --#if __GLASGOW_HASKELL__ < 710---- | Construct tag-less 'Version'------ > showVersion (makeVersion [1,2,3]) == "1.2.3"-makeVersion :: [Int] -> Version-makeVersion b = Version b []--#endif  -- | Read a 'Version' or throw an exception. --
src/Extra.hs view
@@ -8,40 +8,37 @@ module Extra {-# DEPRECATED "This module is provided as documentation of all new functions, you should import the more specific modules directly." #-} (     -- * Control.Concurrent.Extra     -- | Extra functions available in @"Control.Concurrent.Extra"@.-    getNumCapabilities, setNumCapabilities, withNumCapabilities, forkFinally, once, onceFork, Lock, newLock, withLock, withLockTry, Var, newVar, readVar, writeVar, modifyVar, modifyVar_, withVar, Barrier, newBarrier, signalBarrier, waitBarrier, waitBarrierMaybe,+    withNumCapabilities, once, onceFork, Lock, newLock, withLock, withLockTry, Var, newVar, readVar, writeVar, modifyVar, modifyVar_, withVar, Barrier, newBarrier, signalBarrier, waitBarrier, waitBarrierMaybe,     -- * Control.Exception.Extra     -- | Extra functions available in @"Control.Exception.Extra"@.-    Partial, retry, retryBool, errorWithoutStackTrace, showException, stringException, errorIO, displayException, ignore, catch_, handle_, try_, catchJust_, handleJust_, tryJust_, catchBool, handleBool, tryBool,+    Partial, retry, retryBool, errorWithoutStackTrace, showException, stringException, errorIO, ignore, catch_, handle_, try_, catchJust_, handleJust_, tryJust_, catchBool, handleBool, tryBool,     -- * Control.Monad.Extra     -- | Extra functions available in @"Control.Monad.Extra"@.-    whenJust, whenJustM, whenMaybe, whenMaybeM, unit, maybeM, eitherM, loop, loopM, whileM, partitionM, concatMapM, concatForM, mconcatMapM, mapMaybeM, findM, firstJustM, fold1M, fold1M_, whenM, unlessM, ifM, notM, (||^), (&&^), orM, andM, anyM, allM,+    whenJust, whenJustM, whenMaybe, whenMaybeM, unit, maybeM, fromMaybeM, eitherM, loop, loopM, whileM, partitionM, concatMapM, concatForM, mconcatMapM, mapMaybeM, findM, firstJustM, fold1M, fold1M_, whenM, unlessM, ifM, notM, (||^), (&&^), orM, andM, anyM, allM,     -- * Data.Either.Extra     -- | Extra functions available in @"Data.Either.Extra"@.-    isLeft, isRight, fromLeft, fromRight, fromEither, fromLeft', fromRight', eitherToMaybe, maybeToEither, mapLeft, mapRight,+    fromLeft, fromRight, fromEither, fromLeft', fromRight', eitherToMaybe, maybeToEither, mapLeft, mapRight,     -- * Data.IORef.Extra     -- | Extra functions available in @"Data.IORef.Extra"@.-    modifyIORef', writeIORef', atomicModifyIORef', atomicWriteIORef, atomicWriteIORef',+    writeIORef', atomicWriteIORef',     -- * Data.List.Extra     -- | Extra functions available in @"Data.List.Extra"@.-    lower, upper, trim, trimStart, trimEnd, word1, line1, escapeHTML, escapeJSON, unescapeHTML, unescapeJSON, dropEnd, takeEnd, splitAtEnd, breakEnd, spanEnd, dropWhileEnd, dropWhileEnd', takeWhileEnd, stripSuffix, stripInfix, stripInfixEnd, dropPrefix, dropSuffix, wordsBy, linesBy, breakOn, breakOnEnd, splitOn, split, chunksOf, notNull, list, uncons, unsnoc, cons, snoc, drop1, mconcatMap, groupSort, groupSortOn, groupSortBy, nubOrd, nubOrdBy, nubOrdOn, nubOn, groupOn, sortOn, nubSort, nubSortBy, nubSortOn, maximumOn, minimumOn, disjoint, allSame, anySame, repeatedly, for, firstJust, concatUnzip, concatUnzip3, zipFrom, zipWithFrom, replace, merge, mergeBy,+    lower, upper, trim, trimStart, trimEnd, word1, line1, escapeHTML, escapeJSON, unescapeHTML, unescapeJSON, dropEnd, takeEnd, splitAtEnd, breakEnd, spanEnd, dropWhileEnd', takeWhileEnd, stripSuffix, stripInfix, stripInfixEnd, dropPrefix, dropSuffix, wordsBy, linesBy, breakOn, breakOnEnd, splitOn, split, chunksOf, notNull, list, unsnoc, cons, snoc, drop1, mconcatMap, groupSort, groupSortOn, groupSortBy, nubOrd, nubOrdBy, nubOrdOn, nubOn, groupOn, nubSort, nubSortBy, nubSortOn, maximumOn, minimumOn, disjoint, allSame, anySame, repeatedly, for, firstJust, concatUnzip, concatUnzip3, zipFrom, zipWithFrom, replace, merge, mergeBy,+    -- * Data.List.NonEmpty.Extra+    -- | Extra functions available in @"Data.List.NonEmpty.Extra"@.+    (|:), (|>), appendl, appendr, maximum1, minimum1, maximumBy1, minimumBy1, maximumOn1, minimumOn1,     -- * Data.Tuple.Extra     -- | Extra functions available in @"Data.Tuple.Extra"@.     first, second, (***), (&&&), dupe, both, fst3, snd3, thd3, curry3, uncurry3,-    -- * Data.Typeable.Extra-    -- | Extra functions available in @"Data.Typeable.Extra"@.-    typeRep, (:~:)(..), Proxy(..),     -- * Data.Version.Extra     -- | Extra functions available in @"Data.Version.Extra"@.-    makeVersion, readVersion,+    readVersion,     -- * Numeric.Extra     -- | Extra functions available in @"Numeric.Extra"@.     showDP, intToDouble, intToFloat, floatToDouble, doubleToFloat,     -- * System.Directory.Extra     -- | Extra functions available in @"System.Directory.Extra"@.     withCurrentDirectory, createDirectoryPrivate, listContents, listDirectories, listFiles, listFilesInside, listFilesRecursive,-    -- * System.Environment.Extra-    -- | Extra functions available in @"System.Environment.Extra"@.-    getExecutablePath, lookupEnv,     -- * System.Info.Extra     -- | Extra functions available in @"System.Info.Extra"@.     isWindows, isMac,@@ -54,9 +51,6 @@     -- * System.Time.Extra     -- | Extra functions available in @"System.Time.Extra"@.     Seconds, sleep, timeout, showDuration, offsetTime, offsetTimeIncrease, duration,-    -- * Text.Read.Extra-    -- | Extra functions available in @"Text.Read.Extra"@.-    readEither, readMaybe,     ) where  import Control.Concurrent.Extra@@ -65,14 +59,12 @@ import Data.Either.Extra import Data.IORef.Extra import Data.List.Extra+import Data.List.NonEmpty.Extra hiding (cons, snoc, sortOn, union, unionBy) import Data.Tuple.Extra-import Data.Typeable.Extra import Data.Version.Extra import Numeric.Extra import System.Directory.Extra-import System.Environment.Extra import System.Info.Extra import System.IO.Extra import System.Process.Extra import System.Time.Extra-import Text.Read.Extra
src/Numeric/Extra.hs view
@@ -7,8 +7,8 @@     ) where  import Numeric-import Control.Arrow + --------------------------------------------------------------------- -- Data.String @@ -18,8 +18,7 @@ -- > showDP 0 pi == "3" -- > showDP 2 3  == "3.00" showDP :: RealFloat a => Int -> a -> String-showDP n x = a ++ (if n > 0 then "." else "") ++ b ++ replicate (n - length b) '0'-    where (a,b) = second (drop 1) $ break (== '.') $ showFFloat (Just n) x ""+showDP n x = showFFloat (Just n) x ""   ---------------------------------------------------------------------@@ -40,5 +39,3 @@ -- | Specialised numeric conversion, type restricted version of 'realToFrac'. doubleToFloat :: Double -> Float doubleToFloat = realToFrac--
src/System/Environment/Extra.hs view
@@ -1,26 +1,10 @@-{-# LANGUAGE CPP #-}-{-# OPTIONS_GHC -fno-warn-duplicate-exports #-}  -- | Extra functions for "System.Environment". All these functions are available in later GHC versions, --   but this code works all the way back to GHC 7.2.+--+--   Currently this module has no functionality beyond "System.Environment". module System.Environment.Extra(     module System.Environment,-    getExecutablePath, lookupEnv     ) where  import System.Environment--#if __GLASGOW_HASKELL__ < 706-import Control.Exception.Extra-import System.IO.Error-import Data.Functor---- | Alias for 'getProgName' in GHC 7.4 and below, otherwise---   returns the absolute pathname of the current executable.-getExecutablePath :: IO FilePath-getExecutablePath = getProgName---- | Return the value of the environment variable var, or Nothing if there is no such value.-lookupEnv :: String -> IO (Maybe String)-lookupEnv x = catchBool isDoesNotExistError (Just <$> getEnv x) (const $ return Nothing)-#endif
src/Text/Read/Extra.hs view
@@ -1,38 +1,9 @@-{-# LANGUAGE CPP #-}-{-# OPTIONS_GHC -fno-warn-duplicate-exports #-}  -- | This module provides "Text.Read" with functions added in later versions.+--+--   Currently this module has no functionality beyond "Text.Read". module Text.Read.Extra(     module Text.Read,-    readEither, readMaybe     ) where  import Text.Read--#if __GLASGOW_HASKELL__ < 706--import Text.ParserCombinators.ReadP as P---- | Parse a string using the 'Read' instance.--- Succeeds if there is exactly one valid result.--- A 'Left' value indicates a parse error.-readEither :: Read a => String -> Either String a-readEither s =-  case [ x | (x,"") <- readPrec_to_S read' minPrec s ] of-    [x] -> Right x-    []  -> Left "Prelude.read: no parse"-    _   -> Left "Prelude.read: ambiguous parse"- where-  read' =-    do x <- readPrec-       lift P.skipSpaces-       return x---- | Parse a string using the 'Read' instance.--- Succeeds if there is exactly one valid result.-readMaybe :: Read a => String -> Maybe a-readMaybe s = case readEither s of-                Left _  -> Nothing-                Right a -> Just a--#endif
test/TestGen.hs view
@@ -94,9 +94,6 @@     testGen "list 1 (\\v _ -> v - 2) [5,6,7] == 3" $ list 1 (\v _ -> v - 2) [5,6,7] == 3     testGen "list 1 (\\v _ -> v - 2) []      == 1" $ list 1 (\v _ -> v - 2) []      == 1     testGen "\\nil cons xs -> maybe nil (uncurry cons) (uncons xs) == list nil cons xs" $ \nil cons xs -> maybe nil (uncurry cons) (uncons xs) == list nil cons xs-    testGen "uncons \"test\" == Just ('t',\"est\")" $ uncons "test" == Just ('t',"est")-    testGen "uncons \"\"     == Nothing" $ uncons ""     == Nothing-    testGen "\\xs -> uncons xs == if null xs then Nothing else Just (head xs, tail xs)" $ \xs -> uncons xs == if null xs then Nothing else Just (head xs, tail xs)     testGen "unsnoc \"test\" == Just (\"tes\",'t')" $ unsnoc "test" == Just ("tes",'t')     testGen "unsnoc \"\"     == Nothing" $ unsnoc ""     == Nothing     testGen "\\xs -> unsnoc xs == if null xs then Nothing else Just (init xs, last xs)" $ \xs -> unsnoc xs == if null xs then Nothing else Just (init xs, last xs)@@ -151,7 +148,6 @@     testGen "escapeJSON \"\\ttab\\nnewline\\\\\" == \"\\\\ttab\\\\nnewline\\\\\\\\\"" $ escapeJSON "\ttab\nnewline\\" == "\\ttab\\nnewline\\\\"     testGen "escapeJSON \"\\ESC[0mHello\" == \"\\\\u001b[0mHello\"" $ escapeJSON "\ESC[0mHello" == "\\u001b[0mHello"     testGen "\\xs -> unescapeJSON (escapeJSON xs) == xs" $ \xs -> unescapeJSON (escapeJSON xs) == xs-    testGen "sortOn fst [(3,\"z\"),(1,\"\"),(3,\"a\")] == [(1,\"\"),(3,\"z\"),(3,\"a\")]" $ sortOn fst [(3,"z"),(1,""),(3,"a")] == [(1,""),(3,"z"),(3,"a")]     testGen "groupSort [(1,'t'),(3,'t'),(2,'e'),(2,'s')] == [(1,\"t\"),(2,\"es\"),(3,\"t\")]" $ groupSort [(1,'t'),(3,'t'),(2,'e'),(2,'s')] == [(1,"t"),(2,"es"),(3,"t")]     testGen "\\xs -> map fst (groupSort xs) == sort (nub (map fst xs))" $ \xs -> map fst (groupSort xs) == sort (nub (map fst xs))     testGen "\\xs -> concatMap snd (groupSort xs) == map snd (sortOn fst xs)" $ \xs -> concatMap snd (groupSort xs) == map snd (sortOn fst xs)@@ -227,14 +223,17 @@     testGen "\\xs -> nubOrd xs == nub xs" $ \xs -> nubOrd xs == nub xs     testGen "nubOrdOn length [\"a\",\"test\",\"of\",\"this\"] == [\"a\",\"test\",\"of\"]" $ nubOrdOn length ["a","test","of","this"] == ["a","test","of"]     testGen "nubOrdBy (compare `on` length) [\"a\",\"test\",\"of\",\"this\"] == [\"a\",\"test\",\"of\"]" $ nubOrdBy (compare `on` length) ["a","test","of","this"] == ["a","test","of"]+    testGen "(1 :| [2,3]) |> 4 |> 5 == 1 :| [2,3,4,5]" $ (1 :| [2,3]) |> 4 |> 5 == 1 :| [2,3,4,5]+    testGen "[1,2,3] |: 4 |> 5 == 1 :| [2,3,4,5]" $ [1,2,3] |: 4 |> 5 == 1 :| [2,3,4,5]+    testGen "appendl (1 :| [2,3]) [4,5] == 1 :| [2,3,4,5]" $ appendl (1 :| [2,3]) [4,5] == 1 :| [2,3,4,5]+    testGen "appendr [1,2,3] (4 :| [5]) == 1 :| [2,3,4,5]" $ appendr [1,2,3] (4 :| [5]) == 1 :| [2,3,4,5]+    testGen "(1 :| [3, 5, 3]) `union` (4 :| [5, 3, 5, 2]) == 1 :| [3, 5, 3, 4, 2]" $ (1 :| [3, 5, 3]) `union` (4 :| [5, 3, 5, 2]) == 1 :| [3, 5, 3, 4, 2]     testGen "first succ (1,\"test\") == (2,\"test\")" $ first succ (1,"test") == (2,"test")     testGen "second reverse (1,\"test\") == (1,\"tset\")" $ second reverse (1,"test") == (1,"tset")     testGen "(succ *** reverse) (1,\"test\") == (2,\"tset\")" $ (succ *** reverse) (1,"test") == (2,"tset")     testGen "(succ &&& pred) 1 == (2,0)" $ (succ &&& pred) 1 == (2,0)     testGen "dupe 12 == (12, 12)" $ dupe 12 == (12, 12)     testGen "both succ (1,2) == (2,3)" $ both succ (1,2) == (2,3)-    testGen "typeRep (Proxy :: Proxy Int) == typeOf (1 :: Int)" $ typeRep (Proxy :: Proxy Int) == typeOf (1 :: Int)-    testGen "showVersion (makeVersion [1,2,3]) == \"1.2.3\"" $ showVersion (makeVersion [1,2,3]) == "1.2.3"     testGen "\\x -> readVersion (showVersion x) == x" $ \x -> readVersion (showVersion x) == x     testGen "readVersion \"hello\" == undefined" $ erroneous $ readVersion "hello"     testGen "showDP 4 pi == \"3.1416\"" $ showDP 4 pi == "3.1416"
test/TestUtil.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE ScopedTypeVariables, CPP, FlexibleInstances #-}+{-# LANGUAGE ScopedTypeVariables, FlexibleInstances #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -- OK because a test module  module TestUtil@@ -22,7 +22,8 @@ import Data.Either.Extra as X import Data.Function as X import Data.IORef.Extra as X-import Data.List.Extra as X+import Data.List.Extra as X hiding (union, unionBy)+import Data.List.NonEmpty.Extra as X (NonEmpty(..), (|>), (|:), appendl, appendr, union, unionBy) import Data.Monoid as X import Data.Tuple.Extra as X import Data.Typeable.Extra as X@@ -64,11 +65,6 @@ a ==== b     | a == b = True     | otherwise = error $ "Not equal!\n" ++ show a ++ "\n" ++ show b--#if __GLASGOW_HASKELL__ < 707-instance Eq ErrorCall where-    ErrorCall x == ErrorCall y = x == y-#endif  runTests :: IO () -> IO () runTests t = do