generic-override: Provides functionality for overriding instances for generic derivation

This is a package candidate release! Here you can preview how this package release will appear once published to the main package index (which can be accomplished via the 'maintain' link below). Please note that once a package has been published to the main package index it cannot be undone! Please consult the package uploading documentation for more information.

[maintain] [Publish]

Please see the README on GitHub at https://github.com/estatico/generic-override#readme


[Skip to Readme]

Properties

Versions 0.0.0.0, 0.0.0.0, 0.2.0.0, 0.3.0.0, 0.4.0.0
Change log ChangeLog.md
Dependencies base (>=4.7 && <5) [details]
License BSD-3-Clause
Copyright 2020 Estatico Studios LLC
Author Cary Robbins
Maintainer carymrobbins@gmail.com
Category Generics
Home page https://github.com/estatico/generic-override#readme
Bug tracker https://github.com/estatico/generic-override/issues
Source repo head: git clone https://github.com/estatico/generic-override
Uploaded by carymrobbins at 2020-03-31T05:15:38Z

Modules

[Index] [Quick Jump]

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


Readme for generic-override-0.0.0.0

[back to package description]

generic-override

For the associated blog post describing how this works, see Overriding Type Class Instances.


This library provides the ability to override instances used by generic derivation.

Example

-- Needed for constructing our 'Override' type in the DerivingVia clause.
import Data.Override (Override(Override), As)
-- Provides aeson support for generic-override (lives in generic-override-aeson).
import Data.Override.Aeson ()
-- Basic imports we need for the example.
import Data.Aeson (ToJSON(toJSON))
import Data.Text (Text)
import qualified Data.Text as Text

-- | A simple record type. We'll use generic derivation for the 'ToJSON' instance
-- but override the instances used by derivation for the 'String' and 'baz'
-- fields.
data MyRec = MyRec
  { foo :: Int
  , bar :: String
  , baz :: Text
  } deriving stock (Show, Eq, Generic)
    deriving (ToJSON)
      via Override MyRec
            '[ -- Derive the 'String' field via 'CharArray'.
               String `As` CharArray
               -- Derive the 'baz' field via 'Uptext'.
             , "baz" `As` Uptext
             ]

-- | Newtype wrapper to override 'ToJSON Text' instances with ones that
-- encode the 'Text' as uppercase.
newtype Uptext = Uptext { unUptext :: Text }

instance ToJSON Uptext where
  toJSON = toJSON . Text.toUpper . unUptext

-- | Newtype wrapper to override 'ToJSON String' instances with ones that
-- encode the 'String' as a JSON array of characters.
newtype CharArray = CharArray { unCharArray :: String }

instance ToJSON CharArray where
  toJSON = toJSON . map (:[]) . unCharArray

Let's serialize an example MyRec to JSON -

% ghci
> :{
  Data.ByteString.Lazy.Char8.putStrLn
    $ Data.Aeson.encode
    $ Data.Aeson.toJSON MyRec { foo = 12, bar = "hi", baz = "bye" }
  :}
{"foo":12,"bar":["h","i"],"baz":"BYE"}

For more examples, see the test suite in generic-override-aeson.