Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/lysxia/generic-data
Generic data types in Haskell, utilities for GHC.Generics
https://github.com/lysxia/generic-data
deriving generics haskell
Last synced: 4 days ago
JSON representation
Generic data types in Haskell, utilities for GHC.Generics
- Host: GitHub
- URL: https://github.com/lysxia/generic-data
- Owner: Lysxia
- License: mit
- Created: 2018-02-20T05:03:17.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2024-10-19T23:02:12.000Z (17 days ago)
- Last Synced: 2024-10-20T12:30:19.601Z (17 days ago)
- Topics: deriving, generics, haskell
- Language: Haskell
- Homepage: https://hackage.haskell.org/package/generic-data
- Size: 270 KB
- Stars: 44
- Watchers: 4
- Forks: 9
- Open Issues: 8
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Generic data types in Haskell
[![Hackage](https://img.shields.io/hackage/v/generic-data.svg)](https://hackage.haskell.org/package/generic-data)
[![GitHub CI](https://github.com/Lysxia/generic-data/actions/workflows/haskell-ci.yml/badge.svg)](https://github.com/Lysxia/generic-data/actions)Utilities for `GHC.Generics`.
## Generic deriving for standard classes
### Example: generically deriving Semigroup instances for products
Semi-automatic method using `gmappend`
```haskell
data Foo a = Bar [a] [a] deriving Genericinstance Semigroup (Foo a) where
(<>) = gmappend
```This library also synergizes with the `DerivingVia` extension
(introduced in GHC 8.6), thanks to the `Generically` newtype.```haskell
data Foo a = Bar [a] [a]
deriving Generic
deriving Semigroup via (Generically (Foo a))
```These examples can be found in `test/example.hs`.
---
Note for completeness, the first example uses the following extensions and
imports:```haskell
{-# LANGUAGE DeriveGeneric #-}-- base
import Data.Semigroup (Semigroup(..))-- generic-data
import Generic.Data (Generic, gmappend)
import Generic.Data.Orphans ()
```The second example makes these additions on top:
```haskell
{-# LANGUAGE
DerivingStrategies,
DerivingVia #-} -- since GHC 8.6.1-- In addition to the previous imports
import Generic.Data (Generically(..))
```### Supported classes
Supported classes that GHC currently can't derive: `Semigroup`, `Monoid`,
`Applicative`, `Alternative`, `Eq1`, `Ord1`, `Show1`.Other classes from base are also supported, even though GHC can already derive
them:- `Eq`, `Ord`, `Enum`, `Bounded`, `Show`, `Read` (derivable by the standard);
- `Functor`, `Foldable`, `Traversable` (derivable via extensions,
`DeriveFunctor`, etc.).To derive type classes outside of the standard library, it might be worth
taking a look at [one-liner](https://hackage.haskell.org/package/one-liner).## Type metadata
Extract type names, constructor names, number and arities of constructors, etc..
## Type surgery
generic-data offers simple operations (microsurgeries) on generic
representations.More surgeries can be found in
[generic-data-surgery](https://hackage.haskell.org/package/generic-data-surgery),
and suprisingly, in
[generic-lens](https://hackage.haskell.org/package/generic-lens) and
[one-liner](https://hackage.haskell.org/package/one-liner).For more details, see also:
- the module `Generic.Data.Microsurgery`;
- the files `test/lens-surgery.hs` and `one-liner-surgery.hs`.
### Surgery example
Derive an instance of `Show` generically for a record type,
but as if it were not a record.```haskell
{-# LANGUAGE DeriveGeneric #-}
import Generic.Data (Generic, gshowsPrec)
import Generic.Data.Microsurgery (toData, derecordify)-- An example record type
newtype T = T { unT :: Int } deriving Generic-- Naively deriving Show would result in this being shown:
--
-- show (T 3) = "T {unT = 3}"
--
-- But instead, with a simple surgery, unrecordify, we can forget T was
-- declared as a record:
--
-- show (T 3) = "T 3"instance Show T where
showsPrec n = gshowsPrec n . derecordify . toData-- This example can be found in test/microsurgery.hs
```Alternatively, using `DerivingVia`:
```haskell
{-# LANGUAGE DeriveGeneric, DerivingVia #-}
import Generic.Data (Generic) -- Reexported from GHC.Generics-- Constructors must be visible to use DerivingVia
import Generic.Data.Microsurgery (Surgery, Surgery'(..), Generically(..), Derecordify)data V = V { v1 :: Int, v2 :: Int }
deriving Generic
deriving Show via (Surgery Derecordify V)-- show (V {v1 = 3, v2 = 4}) = "V 3 4"
```---
## Related links
generic-data aims to subsume generic deriving features of the following
packages:- [semigroups](https://hackage.haskell.org/package/semigroups): generic
`Semigroup`, `Monoid`, but with a heavier dependency footprint.
- [transformers-compat](https://hackage.haskell.org/package/transformers-compat):
generic `Eq1`, `Ord1`, `Show1`.
- [generic-deriving](https://hackage.haskell.org/package/generic-deriving):
doesn't derive the classes in base (defines clones of these classes as a toy
example); has Template Haskell code to derive `Generic` (not in generic-data).Other relevant links.
- [deriving-compat](https://hackage.haskell.org/package/deriving-compat):
deriving with Template Haskell.
- [one-liner](https://hackage.haskell.org/package/one-liner): another approach
to using `GHC.Generics` to derive instances of many type classes, including
but not restricted to the above classes (this is done in
[one-liner-instances](https://hackage.haskell.org/package/one-liner-instances)).
- [singletons](https://hackage.haskell.org/package/singletons),
[first-class-families](https://hackage.haskell.org/package/first-class-families)
(second one written by me)
libraries for dependently-typed programming in Haskell.
- [coercible-utils](https://hackage.haskell.org/package/coercible-utils):
utilities for coercible types.---
## Internal module policy
Modules under `Generic.Data.Internal` are not subject to any versioning policy.
Breaking changes may apply to them at any time.If something in those modules seems useful, please report it or create a pull
request to export it from an external module.---
All contributions are welcome. Open an issue or a pull request on Github!