quiet 0.1 → 0.2
raw patch · 4 files changed
+77/−38 lines, 4 files
Files
- README.md +20/−14
- quiet.cabal +2/−2
- src/Quiet.hs +41/−19
- test/Spec.hs +14/−3
README.md view
@@ -5,43 +5,49 @@ [![Hackage][hackage-shield]][hackage] [![Travis][travis-shield]][travis] Often one wants to create a `newtype` which has a convenient field-accessor like `unUserId` below, but that makes the derived `Show`-instance overly verbose.+accessor like `unUserId` below, but that unfortunately makes the `Show`+instance which is derived overly verbose. For example: ```hs-newtype UserId = UserId { unUserId :: String } deriving (Show)+newtype UserId = UserId { unUserId :: String }+ deriving (Read, Show) ``` -Renders as:- ``` ghci> show (UserId "simon") UserId {unUserId = "simon"}+ghci> read "UserId {unUserId = \"simon\"}" :: UserId+UserId {unUserId = "simon"} ``` -With 'qshowsPrec' you can have a `Show` instance which doesn't print-the field labels. It will render as if the `unUserId` accessor wasn't-present at all.+With `DerivingVia` `Quiet` you can have a `Show` instance which doesn't+print the field labels. It will render as if the `unUserId` accessor+wasn't present at all. ```hs-newtype UserId = UserId { unUserId :: String } deriving (Generic)--instance Show UserId where showsPrec = qshowsPrec+newtype UserId = UserId { unUserId :: String }+ deriving (Generic)+ deriving (Read, Show) via (Quiet UserId) ``` ``` ghci> show (UserId "simon") UserId "simon"+ghci> read "UserId \"simon\"" :: UserId+UserId "simon" ``` -A compatible `Read` instance can also be derived using `qreadPrec` if-necessary.+If you want to derive `Read` / `Show` without using `DerivingVia` then+you can use `qreadPrec` and `qshowsPrec` directly. ```hs-instance Read UserId where showsPrec = qreadPrec+instance Read UserId where readPrec = qreadPrec+instance Show UserId where showsPrec = qshowsPrec ```++ [hackage]: http://hackage.haskell.org/package/quiet [hackage-shield]: https://img.shields.io/hackage/v/quiet.svg?style=flat
quiet.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 8115fa43cb04ccd92fe9192fc1547bf268155685bac59dcfe87c1933e9c7f7b0+-- hash: bfd3822b32b35aee5958f968ae00d57da6247e3734721d63a91d5791126903ef name: quiet-version: 0.1+version: 0.2 synopsis: Generic deriving of Read/Show with no record labels. description: Please see the README on GitHub at <https://github.com/jacobstanley/quiet#readme> category: Generics
src/Quiet.hs view
@@ -1,52 +1,59 @@ {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE UndecidableInstances #-} -- | Generic deriving of 'Read' / 'Show' with no record labels. ----- Often one wants to create a @newtype@ which has a convieniant field--- accessor like @unUserId@ below, but that makes the derived 'Show'--- instance overly verbose.+-- Often one wants to create a @newtype@ which has a convenient field+-- accessor like @unUserId@ below, but that unfortunately makes the+-- 'Show' instance which is derived overly verbose. -- -- For example: -- -- @--- newtype UserId = UserId { unUserId :: String } deriving (Show)+-- newtype UserId = UserId { unUserId :: String }+-- deriving (Read, Show) -- @ ----- Renders as:--- -- >>> show (UserId "simon") -- UserId {unUserId = "simon"}+-- >>> read "UserId {unUserId = \"simon\"}" :: UserId+-- UserId {unUserId = "simon"} ----- With 'qshowsPrec' you can have a @Show@ instance which doesn't print--- the field labels. It will render as if the @unUserId@ accessor wasn't--- present at all.+-- With @DerivingVia@ 'Quiet' you can have a 'Show' instance which doesn't+-- print the field labels. It will render as if the @unUserId@ accessor+-- wasn't present at all. -- -- @--- newtype UserId = UserId { unUserId :: String } deriving (Generic)------ instance Show UserId where showsPrec = qshowsPrec+-- newtype UserId = UserId { unUserId :: String }+-- deriving (Generic)+-- deriving (Read, Show) via (Quiet UserId) -- @ -- -- >>> show (UserId "simon") -- UserId "simon"+-- >>> read "UserId \"simon\"" :: UserId+-- UserId "simon" ----- A compatible 'Read' instance can also be derived using 'qreadPrec' if--- necessary.+-- If you want to derive 'Read' / 'Show' without using @DerivingVia@ then+-- you can use 'qreadPrec' and 'qshowsPrec' directly. -- -- @--- instance Read UserId where showsPrec = qreadPrec+-- instance Read UserId where readPrec = qreadPrec+-- instance Show UserId where showsPrec = qshowsPrec -- @ -- module Quiet (- qshowsPrec+ Quiet(..)+ , qshowsPrec , qreadPrec ) where -import GHC.Generics (Generic(..), Rep)+import GHC.Generics (Generic(..), Rep)+import GHC.Read (Read(..)) -import Text.ParserCombinators.ReadPrec (ReadPrec)+import Text.ParserCombinators.ReadPrec (ReadPrec) -import Quiet.Internal (ConType(..), QShow(..), QRead(..))+import Quiet.Internal (ConType(..), QShow(..), QRead(..)) -- | This implements a quiet version of 'Text.Show.showsPrec' which omits@@ -60,3 +67,18 @@ qreadPrec :: (Generic a, QRead (Rep a)) => ReadPrec a qreadPrec = fmap to (qreadPrec_ ConPrefix)++-- | Derive 'Read' / 'Show' using @DerivingVia@.+newtype Quiet a =+ Quiet {+ unQuiet :: a+ }++instance (Generic a, QShow (Rep a)) => Show (Quiet a) where+ showsPrec n =+ qshowsPrec n . unQuiet++instance (Generic a, QRead (Rep a)) => Read (Quiet a) where+ readPrec =+ fmap Quiet qreadPrec+
test/Spec.hs view
@@ -1,12 +1,23 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveGeneric #-} +#if __GLASGOW_HASKELL__ >= 860+{-# LANGUAGE DerivingVia #-}+#endif+ import GHC.Generics (Generic)-import Quiet (qshowsPrec)+import Quiet import System.Exit (exitFailure) -newtype UserId = UserId { unUserId :: String } deriving (Generic)-+#if __GLASGOW_HASKELL__ >= 860+newtype UserId = UserId { unUserId :: String }+ deriving (Generic)+ deriving (Show) via (Quiet UserId)+#else+newtype UserId = UserId { unUserId :: String }+ deriving (Generic) instance Show UserId where showsPrec = qshowsPrec+#endif main :: IO () main =