extra 1.4.9 → 1.4.10
raw patch · 11 files changed
+157/−2 lines, 11 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Data.Typeable.Extra: Proxy :: Proxy
+ Data.Typeable.Extra: Refl :: (:~:) k b b
+ Data.Typeable.Extra: data (:~:) (a :: k) (b :: k) :: k -> k -> *
+ Data.Typeable.Extra: data Proxy (t :: k) :: k -> *
+ Data.Typeable.Extra: typeRep :: Typeable k a => proxy a -> TypeRep
+ Extra: Proxy :: Proxy
+ Extra: Refl :: (:~:) k b b
+ Extra: data (:~:) (a :: k) (b :: k) :: k -> k -> *
+ Extra: data Proxy (t :: k) :: k -> *
+ Extra: typeRep :: Typeable k a => proxy a -> TypeRep
Files
- CHANGES.txt +2/−0
- Generate.hs +1/−1
- extra.cabal +2/−1
- src/Data/Either/Extra.hs +3/−0
- src/Data/IORef/Extra.hs +6/−0
- src/Data/Typeable/Extra.hs +129/−0
- src/Extra.hs +4/−0
- src/System/Environment/Extra.hs +3/−0
- test/TestCustom.hs +5/−0
- test/TestGen.hs +1/−0
- test/TestUtil.hs +1/−0
CHANGES.txt view
@@ -1,5 +1,7 @@ Changelog for Extra +1.4.10+ Add Data.Typeable.Extra containing typeRep, Proxy, (:~:) 1.4.9 Add line1 1.4.8
Generate.hs view
@@ -66,7 +66,7 @@ validIdentifier xs =- (take 1 xs == "(" || isName xs) &&+ (take 1 xs == "(" || isName (takeWhile (/= '(') xs)) && xs `notElem` ["module","Numeric"] isName (x:xs) = isAlpha x && all (\x -> isAlphaNum x || x `elem` "_'") xs
extra.cabal view
@@ -1,7 +1,7 @@ cabal-version: >= 1.10 build-type: Simple name: extra-version: 1.4.9+version: 1.4.10 license: BSD3 license-file: LICENSE category: Development@@ -48,6 +48,7 @@ Data.IORef.Extra Data.List.Extra Data.Tuple.Extra+ Data.Typeable.Extra Data.Version.Extra Numeric.Extra System.Directory.Extra
src/Data/Either/Extra.hs view
@@ -1,6 +1,9 @@ {-# LANGUAGE CPP #-} {-# OPTIONS_GHC -fno-warn-duplicate-exports #-} +-- | This module extends "Data.Either" with extra operations, particularly+-- to quickly extract from inside an 'Either'. Some of these operations are+-- partial, and should be used with care in production-quality code. module Data.Either.Extra( module Data.Either, isLeft, isRight, fromLeft, fromRight, fromEither
src/Data/IORef/Extra.hs view
@@ -1,6 +1,8 @@ {-# 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'@@ -31,6 +33,8 @@ 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@@ -38,6 +42,8 @@ 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 (\_ -> (a, ()))
+ src/Data/Typeable/Extra.hs view
@@ -0,0 +1,129 @@+{-# 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.+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/Extra.hs view
@@ -27,6 +27,9 @@ -- * Data.Tuple.Extra -- | Extra functions available in @"Data.Tuple.Extra"@. first, second, (***), (&&&), dupe, both, fst3, snd3, thd3,+ -- * Data.Typeable.Extra+ -- | Extra functions available in @"Data.Typeable.Extra"@.+ typeRep, (:~:)(..), Proxy(..), -- * Data.Version.Extra -- | Extra functions available in @"Data.Version.Extra"@. makeVersion, readVersion,@@ -60,6 +63,7 @@ import Data.IORef.Extra import Data.List.Extra import Data.Tuple.Extra+import Data.Typeable.Extra import Data.Version.Extra import Numeric.Extra import System.Directory.Extra
src/System/Environment/Extra.hs view
@@ -14,9 +14,12 @@ import Control.Exception.Extra import System.IO.Error +-- | 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 (fmap Just $ getEnv x) (const $ return Nothing) #endif
test/TestCustom.hs view
@@ -7,9 +7,14 @@ import Data.IORef import TestUtil +import Extra as X + testCustom :: IO () testCustom = do+ -- check that Extra really does export these things+ testGen "Extra export" $ Proxy == (X.Proxy :: Proxy ())+ testRaw "withTempFile" $ do xs <- replicateM 4 $ onceFork $ do replicateM_ 100 $ withTempFile (const $ return ())
test/TestGen.hs view
@@ -194,6 +194,7 @@ 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"
test/TestUtil.hs view
@@ -22,6 +22,7 @@ import Data.Char as X import Data.Monoid as X import Data.Tuple as X+import Data.Typeable as X import Data.Version as X import System.Directory as X import System.FilePath as X