rel8 1.2.2.0 → 1.3.0.0
raw patch · 23 files changed
+174/−35 lines, 23 filesdep ~hedgehogdep ~opaleyePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: hedgehog, opaleye
API changes (from Hackage documentation)
+ Rel8: avg :: Sql DBSum a => Expr a -> Aggregate a
+ Rel8: class IsMaybe a ~ IsMaybe b => Homonullable a b
+ Rel8: eqTable :: (EqTable a, GTable TEqTable TColumns (Rep (Record a)), Columns a ~ GColumns TColumns (Rep (Record a))) => Columns a (Dict (Sql DBEq))
+ Rel8: ilike :: Expr Text -> Expr Text -> Expr Bool
+ Rel8: like :: Expr Text -> Expr Text -> Expr Bool
+ Rel8: mode :: forall a. EqTable a => Query a -> Query a
+ Rel8: ordTable :: (OrdTable a, GTable TOrdTable TColumns (Rep (Record a)), Columns a ~ GColumns TColumns (Rep (Record a))) => Columns a (Dict (Sql DBOrd))
+ Rel8.Expr.Num: divMod :: Sql DBIntegral a => Expr a -> Expr a -> (Expr a, Expr a)
+ Rel8.Expr.Num: quot :: Sql DBIntegral a => Expr a -> Expr a -> Expr a
+ Rel8.Expr.Num: quotRem :: Sql DBIntegral a => Expr a -> Expr a -> (Expr a, Expr a)
+ Rel8.Expr.Num: rem :: Sql DBIntegral a => Expr a -> Expr a -> Expr a
+ Rel8.Expr.Text: ilike :: Expr Text -> Expr Text -> Expr Bool
+ Rel8.Expr.Text: like :: Expr Text -> Expr Text -> Expr Bool
- Rel8: class DBNum a => DBIntegral a
+ Rel8: class (DBNum a, DBOrd a) => DBIntegral a
Files
- Changelog.md +19/−0
- rel8.cabal +4/−3
- src/Rel8.hs +7/−3
- src/Rel8/Expr/Aggregate.hs +16/−1
- src/Rel8/Expr/Num.hs +39/−6
- src/Rel8/Expr/Opaleye.hs +2/−2
- src/Rel8/Expr/Text.hs +23/−2
- src/Rel8/Generic/Record.hs +1/−0
- src/Rel8/Query/Aggregate.hs +19/−0
- src/Rel8/Query/Exists.hs +1/−1
- src/Rel8/Query/Set.hs +6/−6
- src/Rel8/Schema/HTable/Vectorize.hs +2/−1
- src/Rel8/Schema/Table.hs +3/−0
- src/Rel8/Statement/Select.hs +3/−0
- src/Rel8/Table/HKD.hs +1/−0
- src/Rel8/Table/Opaleye.hs +3/−1
- src/Rel8/Type.hs +8/−8
- src/Rel8/Type/Enum.hs +1/−0
- src/Rel8/Type/JSONBEncoded.hs +4/−0
- src/Rel8/Type/JSONEncoded.hs +4/−0
- src/Rel8/Type/Num.hs +4/−1
- src/Rel8/Type/ReadShow.hs +3/−0
- src/Rel8/Type/Tag.hs +1/−0
Changelog.md view
@@ -1,3 +1,22 @@+# 1.3.0.0 (2022-01-31)++## Breaking changes++* `div` and `mod` have been changed to match Haskell semantics. If you need the PostgreSQL `div()` and `mod()` functions, use `quot` and `rem`. While this is not an API change, we feel this is a breaking change in semantics and have bumped the major version number. ([#155](https://github.com/circuithub/rel8/pull/155))++## New features++* `divMod` and `quotRem` functions have been added, matching Haskell's `Prelude` functions. ([#155](https://github.com/circuithub/rel8/pull/155))+* `avg` and `mode` aggregation functions to find the mean value of an expression, or the most common row in a query, respectively. ([#152](https://github.com/circuithub/rel8/pull/152))+* The full `EqTable` and `OrdTable` classes have been exported, allowing for instances to be manually created. ([#157](https://github.com/circuithub/rel8/pull/157))+* Added `like` and `ilike` (for the `LIKE` and `ILIKE` operators). ([#146](https://github.com/circuithub/rel8/pull/146))++## Other++* Rel8 now requires Opaleye 0.9. ([#158](https://github.com/circuithub/rel8/pull/158))+* Rel8's test suite supports Hedgehog 1.1. ([#160](https://github.com/circuithub/rel8/pull/160))+* The documentation for binary operations has been corrected. ([#162](https://github.com/circuithub/rel8/pull/162))+ # 1.2.2.0 (2021-11-21) ## Other
rel8.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.0 name: rel8-version: 1.2.2.0+version: 1.3.0.0 synopsis: Hey! Hey! Can u rel8? license: BSD3 license-file: LICENSE@@ -27,7 +27,7 @@ , comonad , contravariant , hasql ^>= 1.4.5.1 || ^>= 1.5.0.0- , opaleye ^>= 0.8.0.0+ , opaleye ^>= 0.9.0.0 , pretty , profunctors , product-profunctors@@ -46,6 +46,7 @@ -Wno-missing-import-lists -Wno-prepositive-qualified-module -Wno-monomorphism-restriction -Wno-missing-local-signatures+ -Wno-missing-kind-signatures hs-source-dirs: src exposed-modules:@@ -203,7 +204,7 @@ , containers , hasql , hasql-transaction- , hedgehog ^>=1.0.2+ , hedgehog ^>= 1.0 || ^>= 1.1 , mmorph , rel8 , scientific
src/Rel8.hs view
@@ -46,8 +46,8 @@ , Transposes , AltTable((<|>:)) , AlternativeTable( emptyTable )- , EqTable, (==:), (/=:)- , OrdTable, (<:), (<=:), (>:), (>=:), ascTable, descTable, greatest, least+ , EqTable(..), (==:), (/=:)+ , OrdTable(..), (<:), (<=:), (>:), (>=:), ascTable, descTable, greatest, least , lit , bool , case_@@ -139,6 +139,7 @@ -- ** @null@ , NotNull , Nullable+ , Homonullable , null , nullify , nullable@@ -157,6 +158,7 @@ , (==.), (/=.), (==?), (/=?) , in_ , boolExpr, caseExpr+ , like, ilike -- ** Ordering , DBOrd@@ -225,10 +227,11 @@ , countRows , groupBy , listAgg, listAggExpr+ , mode , nonEmptyAgg, nonEmptyAggExpr , DBMax, max , DBMin, min- , DBSum, sum, sumWhere+ , DBSum, sum, sumWhere, avg , DBString, stringAgg , count , countStar@@ -316,6 +319,7 @@ import Rel8.Expr.Order import Rel8.Expr.Serialize import Rel8.Expr.Sequence+import Rel8.Expr.Text ( like, ilike ) import Rel8.Generic.Rel8able ( KRel8able, Rel8able ) import Rel8.Order import Rel8.Query
src/Rel8/Expr/Aggregate.hs view
@@ -10,6 +10,7 @@ , and, or , min, max , sum, sumWhere+ , avg , stringAgg , groupByExpr , listAggExpr, nonEmptyAggExpr@@ -120,13 +121,27 @@ -- | Corresponds to @sum@. Note that in SQL, @sum@ is type changing - for -- example the @sum@ of @integer@ returns a @bigint@. Rel8 doesn't support--- this, and will add explicit cast back to the original input type. This can+-- this, and will add explicit casts back to the original input type. This can -- lead to overflows, and if you anticipate very large sums, you should upcast -- your input. sum :: Sql DBSum a => Expr a -> Aggregate a sum = unsafeMakeAggregate toPrimExpr (castExpr . fromPrimExpr) $ Just Aggregator { operation = Opaleye.AggrSum+ , ordering = []+ , distinction = Opaleye.AggrAll+ }+++-- | Corresponds to @avg@. Note that in SQL, @avg@ is type changing - for+-- example, the @avg@ of @integer@ returns a @numeric@. Rel8 doesn't support+-- this, and will add explicit casts back to the original input type. If you+-- need a fractional result on an integral column, you should cast your input+-- to 'Double' or 'Data.Scientific.Scientific' before calling 'avg'.+avg :: Sql DBSum a => Expr a -> Aggregate a+avg = unsafeMakeAggregate toPrimExpr (castExpr . fromPrimExpr) $+ Just Aggregator+ { operation = Opaleye.AggrAvg , ordering = [] , distinction = Opaleye.AggrAll }
src/Rel8/Expr/Num.hs view
@@ -4,18 +4,24 @@ {-# options_ghc -fno-warn-redundant-constraints #-} module Rel8.Expr.Num- ( fromIntegral, realToFrac, div, mod, ceiling, floor, round, truncate+ ( fromIntegral+ , realToFrac+ , div, mod, divMod+ , quot, rem, quotRem+ , ceiling, floor, round, truncate ) where -- base-import Prelude ()+import Prelude ( (+), (-), fst, negate, signum, snd ) -- rel import Rel8.Expr ( Expr( Expr ) )+import Rel8.Expr.Eq ( (==.) ) import Rel8.Expr.Function ( function ) import Rel8.Expr.Opaleye ( castExpr ) import Rel8.Schema.Null ( Homonullable, Sql )+import Rel8.Table.Bool ( bool ) import Rel8.Type.Num ( DBFractional, DBIntegral, DBNum ) @@ -42,14 +48,41 @@ ceiling = function "ceiling" --- | Perform integral division. Corresponds to the @div()@ function.+-- | Emulates the behaviour of the Haskell function 'Prelude.div' in+-- PostgreSQL. div :: Sql DBIntegral a => Expr a -> Expr a -> Expr a-div = function "div"+div n d = fst (divMod n d) --- | Corresponds to the @mod()@ function.+-- | Emulates the behaviour of the Haskell function 'Prelude.mod' in+-- PostgreSQL. mod :: Sql DBIntegral a => Expr a -> Expr a -> Expr a-mod = function "mod"+mod n d = snd (divMod n d)+++-- | Simultaneous 'div' and 'mod'.+divMod :: Sql DBIntegral a => Expr a -> Expr a -> (Expr a, Expr a)+divMod n d = bool qr (q - 1, r + d) (signum r ==. negate (signum d))+ where+ qr@(q, r) = quotRem n d+++-- | Perform integral division. Corresponds to the @div()@ function in+-- PostgreSQL, which behaves like Haskell's 'Prelude.quot' rather than+-- 'Prelude.div'.+quot :: Sql DBIntegral a => Expr a -> Expr a -> Expr a+quot = function "div"+++-- | Corresponds to the @mod()@ function in PostgreSQL, which behaves like+-- Haskell's 'Prelude.rem' rather than 'Prelude.mod'.+rem :: Sql DBIntegral a => Expr a -> Expr a -> Expr a+rem = function "mod"+++-- | Simultaneous 'quot' and 'rem'.+quotRem :: Sql DBIntegral a => Expr a -> Expr a -> (Expr a, Expr a)+quotRem n d = (quot n d, rem n d) -- | Round a 'DFractional' to a 'DBIntegral' by rounding to the nearest smaller
src/Rel8/Expr/Opaleye.hs view
@@ -80,9 +80,9 @@ traversePrimExpr f = fmap fromPrimExpr . f . toPrimExpr -toColumn :: Opaleye.PrimExpr -> Opaleye.Column b+toColumn :: Opaleye.PrimExpr -> Opaleye.Field_ n b toColumn = Opaleye.Column -fromColumn :: Opaleye.Column b -> Opaleye.PrimExpr+fromColumn :: Opaleye.Field_ n b -> Opaleye.PrimExpr fromColumn (Opaleye.Column a) = a
src/Rel8/Expr/Text.hs view
@@ -17,6 +17,9 @@ , pgClientEncoding, quoteIdent, quoteLiteral, quoteNullable, regexpReplace , regexpSplitToArray, repeat, replace, reverse, right, rpad, rtrim , splitPart, strpos, substr, translate++ -- * @LIKE@ and @ILIKE@+ , like, ilike ) where @@ -24,7 +27,7 @@ import Data.Bool ( Bool ) import Data.Int ( Int32 ) import Data.Maybe ( Maybe( Nothing, Just ) )-import Prelude ()+import Prelude ( flip ) -- bytestring import Data.ByteString ( ByteString )@@ -49,7 +52,7 @@ -- | Matches regular expression, case sensitive--- +-- -- Corresponds to the @~.@ operator. (~.) :: Expr Text -> Expr Text -> Expr Bool (~.) = binaryOperator "~."@@ -273,3 +276,21 @@ -- | Corresponds to the @translate@ function. translate :: Expr Text -> Expr Text -> Expr Text -> Expr Text translate = function "translate"+++-- | @like x y@ corresponds to the expression @y LIKE x@.+--+-- Note that the arguments to @like@ are swapped. This is to aid currying, so+-- you can write expressions like+-- @filter (like "Rel%" . packageName) =<< each haskellPackages@+like :: Expr Text -> Expr Text -> Expr Bool+like = flip (binaryOperator "LIKE")+++-- | @ilike x y@ corresponds to the expression @y ILIKE x@.+--+-- Note that the arguments to @ilike@ are swapped. This is to aid currying, so+-- you can write expressions like+-- @filter (ilike "Rel%" . packageName) =<< each haskellPackages@+ilike :: Expr Text -> Expr Text -> Expr Bool+ilike = flip (binaryOperator "ILIKE")
src/Rel8/Generic/Record.hs view
@@ -142,6 +142,7 @@ uncount = id +type Record :: Type -> Type newtype Record a = Record { unrecord :: a }
src/Rel8/Query/Aggregate.hs view
@@ -1,13 +1,17 @@ {-# language FlexibleContexts #-} {-# language MonoLocalBinds #-}+{-# language ScopedTypeVariables #-}+{-# language TypeApplications #-} module Rel8.Query.Aggregate ( aggregate , countRows+ , mode ) where -- base+import Data.Functor.Contravariant ( (>$<) ) import Data.Int ( Int64 ) import Prelude @@ -18,9 +22,16 @@ import Rel8.Aggregate ( Aggregates ) import Rel8.Expr ( Expr ) import Rel8.Expr.Aggregate ( countStar )+import Rel8.Expr.Order ( desc ) import Rel8.Query ( Query )+import Rel8.Query.Limit ( limit ) import Rel8.Query.Maybe ( optional ) import Rel8.Query.Opaleye ( mapOpaleye )+import Rel8.Query.Order ( orderBy )+import Rel8.Table ( toColumns )+import Rel8.Table.Aggregate ( hgroupBy )+import Rel8.Table.Cols ( Cols( Cols ), fromCols )+import Rel8.Table.Eq ( EqTable, eqTable ) import Rel8.Table.Opaleye ( aggregator ) import Rel8.Table.Maybe ( maybeTable ) @@ -35,3 +46,11 @@ -- will return @0@. countRows :: Query a -> Query (Expr Int64) countRows = fmap (maybeTable 0 id) . optional . aggregate . fmap (const countStar)+++-- | Return the most common row in a query.+mode :: forall a. EqTable a => Query a -> Query a+mode rows = limit 1 $ fmap (fromCols . snd) $ orderBy (fst >$< desc) $ do+ aggregate $ do+ row <- toColumns <$> rows+ pure (countStar, Cols $ hgroupBy (eqTable @a) row)
src/Rel8/Query/Exists.hs view
@@ -12,7 +12,7 @@ -- opaleye import qualified Opaleye.Exists as Opaleye-import qualified Opaleye.Operators as Opaleye hiding ( exists )+import qualified Opaleye.Operators as Opaleye -- rel8 import Rel8.Expr ( Expr )
src/Rel8/Query/Set.hs view
@@ -23,36 +23,36 @@ -- | Combine the results of two queries of the same type, collapsing--- duplicates. @union a b@ is the same as the SQL statement @x UNION b@.+-- duplicates. @union a b@ is the same as the SQL statement @a UNION b@. union :: EqTable a => Query a -> Query a -> Query a union = zipOpaleyeWith (Opaleye.unionExplicit binaryspec) -- | Combine the results of two queries of the same type, retaining duplicates.--- @unionAll a b@ is the same as the SQL statement @x UNION ALL b@.+-- @unionAll a b@ is the same as the SQL statement @a UNION ALL b@. unionAll :: Table Expr a => Query a -> Query a -> Query a unionAll = zipOpaleyeWith (Opaleye.unionAllExplicit binaryspec) -- | Find the intersection of two queries, collapsing duplicates. @intersect a--- b@ is the same as the SQL statement @x INTERSECT b@.+-- b@ is the same as the SQL statement @a INTERSECT b@. intersect :: EqTable a => Query a -> Query a -> Query a intersect = zipOpaleyeWith (Opaleye.intersectExplicit binaryspec) -- | Find the intersection of two queries, retaining duplicates. @intersectAll--- a b@ is the same as the SQL statement @x INTERSECT ALL b@.+-- a b@ is the same as the SQL statement @a INTERSECT ALL b@. intersectAll :: EqTable a => Query a -> Query a -> Query a intersectAll = zipOpaleyeWith (Opaleye.intersectAllExplicit binaryspec) -- | Find the difference of two queries, collapsing duplicates @except a b@ is--- the same as the SQL statement @x EXCEPT b@.+-- the same as the SQL statement @a EXCEPT b@. except :: EqTable a => Query a -> Query a -> Query a except = zipOpaleyeWith (Opaleye.exceptExplicit binaryspec) -- | Find the difference of two queries, retaining duplicates. @exceptAll a b@--- is the same as the SQL statement @x EXCEPT ALL b@.+-- is the same as the SQL statement @a EXCEPT ALL b@. exceptAll :: EqTable a => Query a -> Query a -> Query a exceptAll = zipOpaleyeWith (Opaleye.exceptAllExplicit binaryspec)
src/Rel8/Schema/HTable/Vectorize.hs view
@@ -27,7 +27,7 @@ where -- base-import Data.Kind ( Type )+import Data.Kind ( Constraint, Type ) import Data.List.NonEmpty ( NonEmpty ) import GHC.Generics (Generic) import Prelude@@ -53,6 +53,7 @@ import Data.Zip ( Unzip, Zip, Zippy(..) ) +type Vector :: (Type -> Type) -> Constraint class Vector list where listNotNull :: proxy a -> Dict NotNull (list a) vectorTypeInformation :: ()
src/Rel8/Schema/Table.hs view
@@ -2,6 +2,7 @@ {-# language DerivingStrategies #-} {-# language DisambiguateRecordFields #-} {-# language NamedFieldPuns #-}+{-# language StandaloneKindSignatures #-} module Rel8.Schema.Table ( TableSchema(..)@@ -10,6 +11,7 @@ where -- base+import Data.Kind ( Type ) import Prelude -- opaleye@@ -26,6 +28,7 @@ -- -- For each selectable table in your database, you should provide a -- @TableSchema@ in order to interact with the table via Rel8.+type TableSchema :: Type -> Type data TableSchema names = TableSchema { name :: String -- ^ The name of the table.
src/Rel8/Statement/Select.hs view
@@ -3,6 +3,7 @@ {-# language FlexibleContexts #-} {-# language MonoLocalBinds #-} {-# language ScopedTypeVariables #-}+{-# language StandaloneKindSignatures #-} {-# language TypeApplications #-} module Rel8.Statement.Select@@ -17,6 +18,7 @@ -- base import Data.Foldable ( toList )+import Data.Kind ( Type ) import Data.List.NonEmpty ( NonEmpty( (:|) ) ) import Data.Void ( Void ) import Prelude hiding ( undefined )@@ -116,6 +118,7 @@ (a, primQuery, _) = Opaleye.runSimpleQueryArrStart (toOpaleye query) () +type Optimized :: Type -> Type data Optimized a = Empty | Unit | Optimized a deriving stock (Functor, Foldable, Traversable)
src/Rel8/Table/HKD.hs view
@@ -157,6 +157,7 @@ => HKDable a +type Top_ :: Constraint class Top_ instance Top_
src/Rel8/Table/Opaleye.hs view
@@ -7,6 +7,8 @@ {-# language TypeFamilies #-} {-# language ViewPatterns #-} +{-# options_ghc -Wno-deprecations #-}+ module Rel8.Table.Opaleye ( aggregator , attributes@@ -137,7 +139,7 @@ {-# INLINABLE unpackspec #-} -valuesspec :: Table Expr a => Opaleye.ValuesspecSafe a a+valuesspec :: Table Expr a => Opaleye.Valuesspec a a valuesspec = Opaleye.ValuesspecSafe (toPackMap undefined) unpackspec
src/Rel8/Type.hs view
@@ -128,10 +128,10 @@ instance DBType Float where typeInformation = TypeInformation { encode = \x -> Opaleye.ConstExpr- if | x == (1 /0) -> Opaleye.OtherLit "'Infinity'"- | isNaN x -> Opaleye.OtherLit "'NaN'"- | x == (-1/0) -> Opaleye.OtherLit "'-Infinity'"- | otherwise -> Opaleye.NumericLit $ realToFrac x+ if | x == (1 / 0) -> Opaleye.OtherLit "'Infinity'"+ | isNaN x -> Opaleye.OtherLit "'NaN'"+ | x == (-1 / 0) -> Opaleye.OtherLit "'-Infinity'"+ | otherwise -> Opaleye.NumericLit $ realToFrac x , decode = Hasql.float4 , typeName = "float4" }@@ -141,10 +141,10 @@ instance DBType Double where typeInformation = TypeInformation { encode = \x -> Opaleye.ConstExpr- if | x == (1 /0) -> Opaleye.OtherLit "'Infinity'"- | isNaN x -> Opaleye.OtherLit "'NaN'"- | x == (-1/0) -> Opaleye.OtherLit "'-Infinity'"- | otherwise -> Opaleye.NumericLit $ realToFrac x+ if | x == (1 / 0) -> Opaleye.OtherLit "'Infinity'"+ | isNaN x -> Opaleye.OtherLit "'NaN'"+ | x == (-1 / 0) -> Opaleye.OtherLit "'-Infinity'"+ | otherwise -> Opaleye.NumericLit $ realToFrac x , decode = Hasql.float8 , typeName = "float8" }
src/Rel8/Type/Enum.hs view
@@ -106,6 +106,7 @@ -- | Types that are sum types, where each constructor is unary (that is, has no -- fields).+type Enumable :: Type -> Constraint class (Generic a, GEnumable (Rep a)) => Enumable a instance (Generic a, GEnumable (Rep a)) => Enumable a
src/Rel8/Type/JSONBEncoded.hs view
@@ -1,3 +1,5 @@+{-# language StandaloneKindSignatures #-}+ module Rel8.Type.JSONBEncoded ( JSONBEncoded(..) ) where -- aeson@@ -6,6 +8,7 @@ -- base import Data.Bifunctor ( first )+import Data.Kind ( Type ) import Prelude -- hasql@@ -20,6 +23,7 @@ -- | Like 'Rel8.JSONEncoded', but works for @jsonb@ columns.+type JSONBEncoded :: Type -> Type newtype JSONBEncoded a = JSONBEncoded { fromJSONBEncoded :: a }
src/Rel8/Type/JSONEncoded.hs view
@@ -1,3 +1,5 @@+{-# language StandaloneKindSignatures #-}+ module Rel8.Type.JSONEncoded ( JSONEncoded(..) ) where -- aeson@@ -5,6 +7,7 @@ import Data.Aeson.Types ( parseEither ) -- base+import Data.Kind ( Type ) import Prelude -- rel8@@ -15,6 +18,7 @@ -- | A deriving-via helper type for column types that store a Haskell value -- using a JSON encoding described by @aeson@'s 'ToJSON' and 'FromJSON' type -- classes.+type JSONEncoded :: Type -> Type newtype JSONEncoded a = JSONEncoded { fromJSONEncoded :: a }
src/Rel8/Type/Num.hs view
@@ -18,6 +18,7 @@ -- rel8 import Rel8.Type ( DBType )+import Rel8.Type.Ord ( DBOrd ) -- scientific import Data.Scientific ( Scientific )@@ -39,13 +40,14 @@ -- expressions. This is a Rel8 concept, and allows us to provide -- 'fromIntegral'. type DBIntegral :: Type -> Constraint-class DBNum a => DBIntegral a+class (DBNum a, DBOrd a) => DBIntegral a instance DBIntegral Int16 instance DBIntegral Int32 instance DBIntegral Int64 -- | The class of database types that support the @/@ operator.+type DBFractional :: Type -> Constraint class DBNum a => DBFractional a instance DBFractional Float instance DBFractional Double@@ -53,6 +55,7 @@ -- | The class of database types that support the @/@ operator.+type DBFloating :: Type -> Constraint class DBFractional a => DBFloating a instance DBFloating Float instance DBFloating Double
src/Rel8/Type/ReadShow.hs view
@@ -1,10 +1,12 @@ {-# language ScopedTypeVariables #-}+{-# language StandaloneKindSignatures #-} {-# language TypeApplications #-} {-# language ViewPatterns #-} module Rel8.Type.ReadShow ( ReadShow(..) ) where -- base+import Data.Kind ( Type ) import Data.Proxy ( Proxy( Proxy ) ) import Data.Typeable ( Typeable, typeRep ) import Prelude @@ -20,6 +22,7 @@ -- | A deriving-via helper type for column types that store a Haskell value -- using a Haskell's 'Read' and 'Show' type classes.+type ReadShow :: Type -> Type newtype ReadShow a = ReadShow { fromReadShow :: a }
src/Rel8/Type/Tag.hs view
@@ -90,6 +90,7 @@ memptyExpr = litExpr mempty +type Tag :: Type newtype Tag = Tag Text deriving newtype ( Eq, Ord, Read, Show