proxied 0.1.1 → 0.2
raw patch · 5 files changed
+401/−10 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Data.Proxied: packageNameProxied :: Datatype d => proxy ((t :: k -> (* -> *) -> * -> *) d f a) -> [Char]
+ Data.Proxied: proxyHashed :: (a -> b) -> Proxy# a -> b
+ Data.Proxied: selDecidedStrictnessProxied :: Selector s => proxy ((t :: k -> (* -> *) -> * -> *) s f a) -> DecidedStrictness
+ Data.Proxied: selSourceStrictnessProxied :: Selector s => proxy ((t :: k -> (* -> *) -> * -> *) s f a) -> SourceStrictness
+ Data.Proxied: selSourceUnpackednessProxied :: Selector s => proxy ((t :: k -> (* -> *) -> * -> *) s f a) -> SourceUnpackedness
+ Data.Proxyless: proxyHashless :: forall a b. (Proxy# a -> b) -> b
+ Data.Proxyless: proxyless :: forall a b. (Proxy a -> b) -> b
+ Data.Proxyless: theAlignment :: forall a. Storable a => Int
+ Data.Proxyless: theBitSize :: forall a. Bits a => Int
+ Data.Proxyless: theBitSizeMaybe :: forall a. Bits a => Maybe Int
+ Data.Proxyless: theConFixity :: forall c. Constructor c => Fixity
+ Data.Proxyless: theConIsRecord :: forall c. Constructor c => Bool
+ Data.Proxyless: theConName :: forall c. Constructor c => [Char]
+ Data.Proxyless: theDataTypeOf :: forall a. Data a => DataType
+ Data.Proxyless: theDatatypeName :: forall d. Datatype d => [Char]
+ Data.Proxyless: theFiniteBitSize :: forall a. FiniteBits a => Int
+ Data.Proxyless: theFloatDigits :: forall a. RealFloat a => Int
+ Data.Proxyless: theFloatRadix :: forall a. RealFloat a => Integer
+ Data.Proxyless: theFloatRange :: forall a. RealFloat a => (Int, Int)
+ Data.Proxyless: theFromLabel :: forall x a. IsLabel x a => a
+ Data.Proxyless: theIsNewtype :: forall d. Datatype d => Bool
+ Data.Proxyless: theIsSigned :: forall a. Bits a => Bool
+ Data.Proxyless: theModuleName :: forall d. Datatype d => [Char]
+ Data.Proxyless: theNatVal :: forall n. KnownNat n => Integer
+ Data.Proxyless: theNatVal' :: forall n. KnownNat n => Integer
+ Data.Proxyless: thePackageName :: forall d. Datatype d => [Char]
+ Data.Proxyless: theParseFormat :: forall a. PrintfArg a => ModifierParser
+ Data.Proxyless: theSameNat :: forall a b. (KnownNat a, KnownNat b) => Maybe (a :~: b)
+ Data.Proxyless: theSameSymbol :: forall a b. (KnownSymbol a, KnownSymbol b) => Maybe (a :~: b)
+ Data.Proxyless: theSelDecidedStrictness :: forall s. Selector s => DecidedStrictness
+ Data.Proxyless: theSelName :: forall s. Selector s => [Char]
+ Data.Proxyless: theSelSourceStrictness :: forall s. Selector s => SourceStrictness
+ Data.Proxyless: theSelSourceUnpackedness :: forall s. Selector s => SourceUnpackedness
+ Data.Proxyless: theSizeOf :: forall a. Storable a => Int
+ Data.Proxyless: theSomeNat :: forall n. KnownNat n => SomeNat
+ Data.Proxyless: theSomeSymbol :: forall n. KnownSymbol n => SomeSymbol
+ Data.Proxyless: theSymbolVal :: forall n. KnownSymbol n => String
+ Data.Proxyless: theSymbolVal' :: forall n. KnownSymbol n => String
+ Data.Proxyless: theTypeNatTypeRep :: forall a. KnownNat a => TypeRep
+ Data.Proxyless: theTypeRep :: forall a. Typeable a => TypeRep
+ Data.Proxyless: theTypeRep# :: forall a. Typeable a => TypeRep
+ Data.Proxyless: theTypeSymbolTypeRep :: forall a. KnownSymbol a => TypeRep
+ Data.Proxyless: undefinedless :: forall a b. (a -> b) -> b
- Data.Proxied: conFixityProxied :: Constructor c => proxy ((t :: * -> (* -> *) -> * -> *) c f a) -> Fixity
+ Data.Proxied: conFixityProxied :: Constructor c => proxy ((t :: k -> (* -> *) -> * -> *) c f a) -> Fixity
- Data.Proxied: conIsRecordProxied :: Constructor c => proxy ((t :: * -> (* -> *) -> * -> *) c f a) -> Bool
+ Data.Proxied: conIsRecordProxied :: Constructor c => proxy ((t :: k -> (* -> *) -> * -> *) c f a) -> Bool
- Data.Proxied: conNameProxied :: Constructor c => proxy ((t :: * -> (* -> *) -> * -> *) c f a) -> [Char]
+ Data.Proxied: conNameProxied :: Constructor c => proxy ((t :: k -> (* -> *) -> * -> *) c f a) -> [Char]
- Data.Proxied: datatypeNameProxied :: Datatype d => proxy ((t :: * -> (* -> *) -> * -> *) d f a) -> [Char]
+ Data.Proxied: datatypeNameProxied :: Datatype d => proxy ((t :: k -> (* -> *) -> * -> *) d f a) -> [Char]
- Data.Proxied: isNewtypeProxied :: Datatype d => proxy ((t :: * -> (* -> *) -> * -> *) d f a) -> Bool
+ Data.Proxied: isNewtypeProxied :: Datatype d => proxy ((t :: k -> (* -> *) -> * -> *) d f a) -> Bool
- Data.Proxied: moduleNameProxied :: Datatype d => proxy ((t :: * -> (* -> *) -> * -> *) d f a) -> [Char]
+ Data.Proxied: moduleNameProxied :: Datatype d => proxy ((t :: k -> (* -> *) -> * -> *) d f a) -> [Char]
- Data.Proxied: selNameProxied :: Selector s => proxy ((t :: * -> (* -> *) -> * -> *) s f a) -> [Char]
+ Data.Proxied: selNameProxied :: Selector s => proxy ((t :: k -> (* -> *) -> * -> *) s f a) -> [Char]
Files
- CHANGELOG.md +4/−0
- README.md +3/−1
- proxied.cabal +17/−8
- src/Data/Proxied.hs +15/−1
- src/Data/Proxyless.hs +362/−0
CHANGELOG.md view
@@ -1,3 +1,7 @@+## 0.2+* Added the `Data.Proxyless` module+* Added `proxyHashed` to `Data.Proxied`+ ### 0.1.1 * Enabled `Safe`
README.md view
@@ -15,6 +15,8 @@ https://tldrlegal.com/license/bsd-3-clause-license-%28revised%29 "BSD 3-Clause License (Revised)" -`proxied` is a simple library that exports a function to convert constant functions to ones that take a `proxy` value. This is useful for retrofiting typeclasses that have functions that return a constant value for any value of a particular type (but still need to consume some value, since one of the parameterized types must appear in a typeclass function). Often, these functions are given `undefined` as an argument, which might be considered poor design.+`proxied` is a simple library that exports a function to convert constant functions to ones that take a `proxy` value in the `Data.Proxied`. This is useful for retrofiting typeclasses that have functions that return a constant value for any value of a particular type (but still need to consume some value, since one of the parameterized types must appear in a typeclass function). Often, these functions are given `undefined` as an argument, which might be considered poor design. `Proxy`, however, does not carry any of the error-throwing risks of `undefined`, so it is much more preferable to take `Proxy` as an argument to a constant function instead of `undefined`. Unfortunately, `Proxy` was included in `base` until GHC 7.8, so many of `base`'s typeclasses still contain constant functions that aren't amenable to passing `Proxy`. `proxied` addresses this issue by providing variants of those typeclass functions that take an explicit `proxy` value.++This library also contains the "Data.Proxyless" module, which works in the opposite direction. That is, one can take functions which take `Proxy` (or `undefined`) as an argument and convert them to functions which take no arguments. This trick relies on the `-XTypeApplications` extension, so it is only available with GHC 8.0 or later.
proxied.cabal view
@@ -1,15 +1,15 @@ name: proxied-version: 0.1.1+version: 0.2 synopsis: Make functions consume Proxy instead of undefined description: @proxied@ is a simple library that exports a function to convert constant functions to ones that take a @proxy@- value. This is useful for retrofiting typeclasses that- have functions that return a constant value for any value- of a particular type (but still need to consume some- value, since one of the parameterized types must appear- in a typeclass function). Often, these functions are- given @undefined@ as an argument, which might be- considered poor design.+ value in the "Data.Proxied" module. This is useful for+ retrofiting typeclasses that have functions that return a+ constant value for any value of a particular type (but+ still need to consume some value, since one of the+ parameterized types must appear in a typeclass function).+ Often, these functions are given @undefined@ as an+ argument, which might be considered poor design. . @Proxy@, however, does not carry any of the error-throwing risks of @undefined@, so it is much more@@ -20,6 +20,13 @@ amenable to passing @Proxy@. @proxied@ addresses this issue by providing variants of those typeclass functions that take an explicit @proxy@ value.+ .+ This library also contains the "Data.Proxyless" module,+ which works in the opposite direction. That is, one can+ take functions which take @Proxy@ (or @undefined@) as an+ argument and convert them to functions which take no+ arguments. This trick relies on the @-XTypeApplications@+ extension, so it is only available with GHC 8.0 or later. homepage: https://github.com/RyanGlScott/proxied bug-reports: https://github.com/RyanGlScott/proxied/issues license: BSD3@@ -46,6 +53,8 @@ library exposed-modules: Data.Proxied+ if impl(ghc >= 8.0)+ exposed-modules: Data.Proxyless build-depends: base >= 4.3 && < 5 , generic-deriving >= 1.10.1 && < 2 , tagged >= 0.4.4 && < 1
src/Data/Proxied.hs view
@@ -1,8 +1,9 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE KindSignatures #-}+{-# LANGUAGE MagicHash #-} #if __GLASGOW_HASKELL__ >= 702-{-# LANGUAGE Safe #-}+{-# LANGUAGE Trustworthy #-} #endif #if __GLASGOW_HASKELL__ >= 706@@ -26,6 +27,9 @@ module Data.Proxied ( -- * 'proxied' and 'unproxied' proxied+#if MIN_VERSION_base(4,7,0)+ , proxyHashed+#endif , unproxied , module Data.Proxy -- * Proxified functions@@ -82,6 +86,7 @@ #if MIN_VERSION_base(4,7,0) import Data.Bits (FiniteBits(..))+import GHC.Exts (Proxy#) import Text.Printf (PrintfArg(..), ModifierParser) #endif @@ -90,6 +95,15 @@ -- /Since: 0.1/ proxied :: (a -> b) -> proxy a -> b proxied f _ = f undefined++#if MIN_VERSION_base(4,7,0)+-- | Converts a constant function to one that takes a @Proxy#@ argument.+-- This function is only available with @base-4.7@ or later.+--+-- /Since: 0.2/+proxyHashed :: (a -> b) -> Proxy# a -> b+proxyHashed f _ = f undefined+#endif -- | Converts a constant function that takes a 'Proxy' argument to one that -- doesn't require a @proxy@ argument. (I'm not sure why you'd want this,
+ src/Data/Proxyless.hs view
@@ -0,0 +1,362 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE Trustworthy #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeOperators #-}++{-# LANGUAGE ViewPatterns #-}++{-# OPTIONS_GHC -Wno-deprecations #-}+{-# OPTIONS_GHC -Wno-type-defaults #-} -- Needed due to GHC Trac #11947++{-|+Module: Data.Proxyless+Copyright: (C) 2016 Ryan Scott+License: BSD-style (see the file LICENSE)+Maintainer: Ryan Scott+Stability: Provisional+Portability: GHC++Remove the 'Proxy', 'Proxy#', and 'undefined' arguments from functions with+'proxyless', 'proxyHashless', and 'undefinedless', respectively, which produce+functions that take type information via GHC's @-XTypeApplications@ extension.++This module is only available with GHC 8.0 or later.++/Since: 0.2/+-}+module Data.Proxyless (+ -- * 'proxyless', 'proxyHashless', and 'undefinedless'+ proxyless+ , proxyHashless+ , undefinedless+ -- * Proxyless functions+ -- ** "Data.Bits"+ , theBitSize+ , theIsSigned+ , theBitSizeMaybe+ , theFiniteBitSize+ -- ** "Data.Data"+ , theDataTypeOf+ -- ** "Data.Typeable"+ , theTypeNatTypeRep+ , theTypeRep+ , theTypeRep#+ , theTypeSymbolTypeRep+ -- ** "Foreign.Storable"+ , theSizeOf+ , theAlignment+ -- ** "GHC.Generics"+ , theDatatypeName+ , theModuleName+ , theIsNewtype+ , thePackageName+ , theConName+ , theConFixity+ , theConIsRecord+ , theSelName+ , theSelSourceUnpackedness+ , theSelSourceStrictness+ , theSelDecidedStrictness+ -- ** "GHC.OverloadedLabels"+ , theFromLabel+ -- ** "GHC.TypeLits"+ , theNatVal+ , theNatVal'+ , theSameNat+ , theSameSymbol+ , theSomeNat+ , theSomeSymbol+ , theSymbolVal+ , theSymbolVal'+ -- ** "Prelude"+ , theFloatRadix+ , theFloatDigits+ , theFloatRange+ -- ** "Text.Printf"+ , theParseFormat+ ) where++import Data.Bits (Bits(..), FiniteBits(..))+import Data.Data hiding (Fixity)+import Data.Proxy (Proxy(..))+import Data.Type.Equality ((:~:))+import Data.Typeable.Internal (Typeable(..), typeNatTypeRep, typeSymbolTypeRep)++import Foreign.Storable (Storable(..))++import GHC.Exts (Proxy#, proxy#)+import GHC.Generics+import GHC.OverloadedLabels (IsLabel(..))+import GHC.TypeLits++import Text.Printf (PrintfArg(..), ModifierParser)++-- | Converts a constant function that takes a 'Proxy' argument to one that+-- doesn't require an argument.+--+-- /Since: 0.2/+proxyless :: forall a b. (Proxy a -> b) -> b+proxyless f = f Proxy++-- | Converts a constant function that takes a 'Proxy#' argument to one that+-- doesn't require an argument.+--+-- /Since: 0.2/+proxyHashless :: forall a b. (Proxy# a -> b) -> b+proxyHashless f = f proxy#++-- | Converts a constant function that takes an 'undefined' argument to one that+-- doesn't require an argument.+--+-- /Since: 0.2/+undefinedless :: forall a b. (a -> b) -> b+undefinedless f = f undefined++-------------------------------------------------------------------------------+-- Data.Bits+-------------------------------------------------------------------------------++-- | @'theBitSize' = 'undefinedless' 'bitSize'@+--+-- /Since: 0.2/+theBitSize :: forall a. Bits a => Int+theBitSize = undefinedless @a bitSize++-- | @'theIsSigned' = 'undefinedless' 'isSigned'@+--+-- /Since: 0.2/+theIsSigned :: forall a. Bits a => Bool+theIsSigned = undefinedless @a isSigned++-- | @'theBitSizeMaybe' = 'undefinedless' 'bitSizeMaybe'@+--+-- /Since: 0.2/+theBitSizeMaybe :: forall a. Bits a => Maybe Int+theBitSizeMaybe = undefinedless @a bitSizeMaybe++-- | @'theFiniteBitSize' = 'undefinedless' 'finiteBitSize'@+--+-- /Since: 0.2/+theFiniteBitSize :: forall a. FiniteBits a => Int+theFiniteBitSize = undefinedless @a finiteBitSize++-------------------------------------------------------------------------------+-- Data.Data+-------------------------------------------------------------------------------++-- | @'theDataTypeOf' = 'undefinedless' 'dataTypeOf'@+--+-- /Since: 0.2/+theDataTypeOf :: forall a. Data a => DataType+theDataTypeOf = undefinedless @a dataTypeOf++-------------------------------------------------------------------------------+-- Data.Typeable+-------------------------------------------------------------------------------++-- | @'theTypeNatTypeRep' = 'proxyHashless' 'typeNatTypeRep'@+--+-- /Since: 0.2/+theTypeNatTypeRep :: forall a. KnownNat a => TypeRep+theTypeNatTypeRep = proxyHashless @a typeNatTypeRep++-- | @'theTypeRep' = 'proxyless' 'typeRep'@+--+-- /Since: 0.2/+theTypeRep :: forall a. Typeable a => TypeRep+theTypeRep = proxyless @a typeRep++-- | @'theTypeRep#' = 'proxyHashless' 'typeRep#'@+--+-- /Since: 0.2/+theTypeRep# :: forall a. Typeable a => TypeRep+theTypeRep# = proxyHashless @a typeRep#++-- | @'theTypeSymbolTypeRep' = 'proxyHashless' 'typeSymbolTypeRep'@+--+-- /Since: 0.2/+theTypeSymbolTypeRep :: forall a. KnownSymbol a => TypeRep+theTypeSymbolTypeRep = proxyHashless @a typeSymbolTypeRep++-------------------------------------------------------------------------------+-- Foreign.Storable+-------------------------------------------------------------------------------++-- | @'theSizeOf' = 'undefinedless' 'sizeOf'@+--+-- /Since: 0.2/+theSizeOf :: forall a. Storable a => Int+theSizeOf = undefinedless @a sizeOf++-- | @'theAlignment' = 'undefinedless' 'alignment'@+--+-- /Since: 0.2/+theAlignment :: forall a. Storable a => Int+theAlignment = undefinedless @a alignment++-------------------------------------------------------------------------------+-- GHC.Generics+-------------------------------------------------------------------------------++-- | @'theDatatypeName' = 'datatypeName' 'undefined'@+--+-- /Since: 0.2/+theDatatypeName :: forall d. Datatype d => [Char]+theDatatypeName = datatypeName @d undefined++-- | @'theModuleName' = 'moduleName' 'undefined'@+--+-- /Since: 0.2/+theModuleName :: forall d. Datatype d => [Char]+theModuleName = moduleName @d undefined++-- | @'theIsNewtype' = 'isNewtype' 'undefined'@+--+-- /Since: 0.2/+theIsNewtype :: forall d. Datatype d => Bool+theIsNewtype = isNewtype @d undefined++-- | @'thePackageName' = 'packageName' 'undefined'@+--+-- /Since: 0.2/+thePackageName :: forall d. Datatype d => [Char]+thePackageName = packageName @d undefined++-- | @'theConName' = 'conName' 'undefined'@+--+-- /Since: 0.2/+theConName :: forall c. Constructor c => [Char]+theConName = conName @c undefined++-- | @'theConFixity' = 'conFixity' 'undefined'@+--+-- /Since: 0.2/+theConFixity :: forall c. Constructor c => Fixity+theConFixity = conFixity @c undefined++-- | @'theConIsRecord' = 'conIsRecord' 'undefined'@+--+-- /Since: 0.2/+theConIsRecord :: forall c. Constructor c => Bool+theConIsRecord = conIsRecord @c undefined++-- | @'theSelName' = 'selName' 'undefined'@+--+-- /Since: 0.2/+theSelName :: forall s. Selector s => [Char]+theSelName = selName @s undefined++-- | @'theSelSourceUnpackedness' = 'selSourceUnpackedness' 'undefined'@+--+-- /Since: 0.2/+theSelSourceUnpackedness :: forall s. Selector s => SourceUnpackedness+theSelSourceUnpackedness = selSourceUnpackedness @s undefined++-- | @'theSelSourceStrictness' = 'selSourceStrictness' 'undefined'@+--+-- /Since: 0.2/+theSelSourceStrictness :: forall s. Selector s => SourceStrictness+theSelSourceStrictness = selSourceStrictness @s undefined++-- | @'theSelDecidedStrictness' = 'selDecidedStrictness' 'undefined'@+--+-- /Since: 0.2/+theSelDecidedStrictness :: forall s. Selector s => DecidedStrictness+theSelDecidedStrictness = selDecidedStrictness @s undefined++-------------------------------------------------------------------------------+-- GHC.Generics+-------------------------------------------------------------------------------++-- | @'theFromLabel' = 'proxyHashless' 'fromLabel'@+--+-- /Since: 0.2/+theFromLabel :: forall x a. IsLabel x a => a+theFromLabel = proxyHashless @x fromLabel++-------------------------------------------------------------------------------+-- GHC.TypeLits+-------------------------------------------------------------------------------++-- | @'theNatVal' = 'proxyless' 'natVal'@+--+-- /Since: 0.2/+theNatVal :: forall n. KnownNat n => Integer+theNatVal = proxyless @n natVal++-- | @`theNatVal'` = 'proxyHashless' `natVal'`@+--+-- /Since: 0.2/+theNatVal' :: forall n. KnownNat n => Integer+theNatVal' = proxyHashless @n natVal'++-- | @'theSameNat' = 'sameNat' 'Proxy' 'Proxy'@+--+-- /Since: 0.2/+theSameNat :: forall a b. (KnownNat a, KnownNat b) => Maybe (a :~: b)+theSameNat = sameNat (Proxy @a) (Proxy @b)++-- | @'theSameSymbol' = 'sameSymbol' 'Proxy' 'Proxy'@+--+-- /Since: 0.2/+theSameSymbol :: forall a b. (KnownSymbol a, KnownSymbol b) => Maybe (a :~: b)+theSameSymbol = sameSymbol (Proxy @a) (Proxy @b)++-- | @'theSomeNat' = 'proxyless' 'SomeNat'@+--+-- /Since: 0.2/+theSomeNat :: forall n. KnownNat n => SomeNat+theSomeNat = proxyless @n SomeNat++-- | @'theSomeSymbol' = 'proxyless' 'SomeSymbol'@+--+-- /Since: 0.2/+theSomeSymbol :: forall n. KnownSymbol n => SomeSymbol+theSomeSymbol = proxyless @n SomeSymbol++-- | @'theSymbolVal' = 'proxyless' 'symbolVal'@+--+-- /Since: 0.2/+theSymbolVal :: forall n. KnownSymbol n => String+theSymbolVal = proxyless @n symbolVal++-- | @`theSymbolVal'` = 'proxyHashless' `symbolVal'`@+--+-- /Since: 0.2/+theSymbolVal' :: forall n. KnownSymbol n => String+theSymbolVal' = proxyHashless @n symbolVal'++-------------------------------------------------------------------------------+-- Prelude+-------------------------------------------------------------------------------++-- | @'theFloatRadix' = 'undefinedless' 'floatRadix'@+--+-- /Since: 0.2/+theFloatRadix :: forall a. RealFloat a => Integer+theFloatRadix = undefinedless @a floatRadix++-- | @'theFloatDigits' = 'undefinedless' 'floatDigits'@+--+-- /Since: 0.2/+theFloatDigits :: forall a. RealFloat a => Int+theFloatDigits = undefinedless @a floatDigits++-- | @'theFloatRange' = 'undefinedless' 'floatRange'@+--+-- /Since: 0.2/+theFloatRange :: forall a. RealFloat a => (Int, Int)+theFloatRange = undefinedless @a floatRange++-------------------------------------------------------------------------------+-- Text.Printf+-------------------------------------------------------------------------------++-- | @'theParseFormat' = 'undefinedless' 'parseFormat'@+--+-- /Since: 0.2/+theParseFormat :: forall a. PrintfArg a => ModifierParser+theParseFormat = undefinedless @a parseFormat