# overloaded-records

Overloaded Records based on current GHC proposal. https://github.com/trskop/overloaded-records

LTS Haskell 9.21: | [email protected]:1 |

Stackage Nightly 2017-07-25: | [email protected]:1 |

Latest on Hackage: | [email protected]:1 |

**Peter Trško**

**[email protected]**

#### Module documentation for 0.4.2.0

`[email protected]:d9facb383b2a9eaff023753b26737b7c5fb0b35af0f0dd3aa1ccb9e9b02c7605,5613`

# Overloaded Records

## Description

Implementation of *Overloaded Record Fields* based on current GHC proposal. It
is built on top of functionality that is included in GHC 8.0.1, but it works on
older GHC versions as well. Most importantly, this library provides Template
Haskell functions for automatic deriving of instancess for `HasField`

and
`ModifyField`

type classes. With these instances overloaded fields can be used
directly as getters and lenses.

```
import Data.Default (Default(def))
import Data.OverloadedRecords.TH (overloadedRecord)
newtype Bar a = Bar {_bar :: a}
overloadedRecord def ''Bar
```

On GHC 8.0.1 it is possible to just write:

```
{-# LANGUAGE OverloadedLabels #-}
import Control.Lens ((+~))
add :: Int -> Bar Int -> Bar Int
add n = #bar +~ n
```

For older GHC versions there is a family of Template Haskell functions that will derive overloaded labels in form of standard haskell definitions:

```
import Control.Lens ((+~))
import Data.OverloadedLabels.TH (label)
label "bar"
add :: Int -> Bar Int -> Bar Int
add n = bar +~ n
```

More about the current status of OverloadedRecordFields language extension can be found on GHC Wiki: OverloadedRecordFields.

## Usage Example

Following is a more complex usage example that demonstrates some of the
possibilities of *Overloaded Labels* provided by this library.

```
-- Basic set of language extensions required when defining instances for
-- classes and type families from "Data.OverloadedRecords".
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
-- Following language extensions are required by code like this:
{-# LANGUAGE ConstraintKinds #-}
-- Codomain of type family 'R' is a 'Constraint' kind.
{-# LANGUAGE FlexibleContexts #-}
-- Required in example when field type (second argument of ':::') is a
-- specific type instead of a polymorphic type.
{-# LANGUAGE TypeOperators #-}
-- Required due to usage of ':::' type alias.
-- Following language extensions are available only in GHC >=8:
{-# LANGUAGE OverloadedLabels #-}
-- Enables #label syntactic sugar.
module Example
where
import Data.Default (Default(def))
-- Provided by one of these packages:
--
-- * data-default
-- * data-default-extra
import Data.OverloadedRecords
import Data.OverloadedRecords.TH (overloadedRecord)
data V3 a = V3
{ v3x :: !a
, v3y :: !a
, v3z :: !a
}
deriving Show
-- Following line derives instances for various type classes and type
-- families that are provided by the overloaded-records library.
--
-- However with def (default settings) this is done only for fields that
-- start with type name, data constructor name, or underscore. Prefix is
-- stripped. In example "v3x" is transformed in to "x" and so would be
-- "_x".
overloadedRecord def ''V3
data V4 a = V4
{ v4x :: !a
, v4y :: !a
, v4z :: !a
, v4t :: !a
}
deriving Show
overloadedRecord def ''V4
zeroV3
:: (Num a, R '["x" ::: a, "y" ::: a, "z" ::: a] r)
=> r -> r
zeroV3 = set' #x 0 . set' #y 0 . set' #z 0
```

The following type signatures for `zeroV3`

are equivalent:

```
zeroV3
:: (Num a, R '["x" ::: a, "y" ::: a, "z" ::: a] r)
=> r -> r
```

```
zeroV3
:: ( Num a
, ModifyField' "x" r a
, ModifyField' "y" r a
, ModifyField' "z" r a
)
=> r -> r
```

One of the biggest features of *Overloaded Records* is the possibility to
define functions that do not depend on concrete data types, but on the “fields”
they provide. In example function `zeroV3`

can be applied to anything that has
fields `"x"`

, `"y"`

, and `"z"`

that reference values of some `Num`

type:

```
λ> zeroV3 (V3 1 1 1 :: V3 Int)
V3 {_x = 0, _y = 0, _z = 0}
```

```
λ> zeroV3 (V4 1 1 1 1 :: V4 Int)
V4 {_x = 0, _y = 0, _z = 0, _t = 1}
```

Function `zeroV3`

can be also defined using operators from
lens library:

```
import Control.Lens ((.~), simple)
zeroV3
:: (Num a, R '["x" ::: a, "y" ::: a, "z" ::: a] r)
=> r -> r
zeroV3 r = r
& #x . simple .~ 0
& #y . simple .~ 0
& #z . simple .~ 0
```

## License

The BSD 3-Clause License, see LICENSE file for details. This implementation is based on original prototype, which is under MIT License.

## Contributions

Contributions, pull requests and bug reports are welcome! Please don’t be afraid to contact author using GitHub or by e-mail.

## Related Work

- ruin is a DSL for working with record types that also leverages OverloadedLabels language extension.
- vinyl provides extensible records for Haskell with lenses using modern GHC features.

## Changes

# ChangeLog / ReleaseNotes

## Version 0.4.2.0

`Rec`

instances for`Eq1`

,`Ord1`

,`Show1`

,`Eq`

,`Ord`

, and`Show`

. Instances for`Eq1`

,`Ord1`

and`Show1`

are available only with transformers ==0.5.* or with base >=4.9 (i.e. GHC >=8). (**new**)- Introducing
`WrappedLensLike`

data type along with a simplified type`WrappedLensLike'`

. For each of these we have corresponding`lns`

and`lns'`

operation for unpacking`WrappedLensLike`

. (**new**)`lns :: WrappedLensLike f s t a b -> (a -> f b) -> s -> f t`

`lns' :: WrappedLensLike' f s a -> (a -> f a) -> s -> f s`

- Allowing fields/accessors to occur in multiple data constructors by not
creating duplicit instances, thanks to
Andy Morris. See
pull request #2.
(
**change**) - Data type
`Label (l :: Symbol)`

that can be used to pass label value around. (**new**) - Instances for
`fst`

,`snd`

,`thd`

and`curry`

fields for 11-tuples, 12-tuples up to 15-tuples. (**new**) - Instances for
`head`

and`tail`

fields for`NonEmpty`

list. (**new**) - Instances for
`HasField`

and`ModifyField`

`Rec context r`

where`r`

is monomorphic. This is just a poor man’s instance, since its usability is very limited, but helpful in those special cases. Hopefully we will be able to find a way how to define overloaded records machinery for`Rec context r`

in general. (**new**)

## Version 0.4.1.0

- Introducing
`Getter`

newtype along with`get`

function. (**new**)`get :: Getter s a -> s -> a`

- Introducing
`Rec`

data type that allows passing polymorphic record along with its instances as a normal value. (**new**) - Corrections and updates in documentation (
**change**) - Uploaded to Hackage: http://hackage.haskell.org/package/overloaded-records-0.4.1.0

## Version 0.4.0.0

- Renamed
`SetField`

type class to`ModifyField`

, it now contains following methods (**breaking change**):`modifyField :: Proxy# l -> (a -> b) -> s -> t`

`setField :: Proxy# l -> s -> b -> t`

`fieldLens :: Functor f => Proxy# l -> (a -> f b) -> s -> f t`

- Instances for tuples (i.e.
`(a, b)`

,`(a, b, c)`

, …) and lists (i.e.`[a]`

). (**new**) - Definitions from
`Data.OverloadedRecords.TH`

were moved to`Data.OverloadedRecords.TH.Internal`

, so that API can be split in to stable and unstable (internal) API. (**change**) - Aliases
`HasField'`

and`ModifyField'`

that enforce`s = t`

and`a = b`

. This is similar to definitions like`Lens'`

. Simplified versions of methods and functions are included using the same naming convention. (**new**) `Setter`

and`Setter'`

changed to type aliases for`Modifier`

type. (**breaking change**)- Introducing
`Setting`

type alias for`Modifier`

along with`setting`

, which is an alternative to`set`

operation. (**new**)`setting :: Setting a s t b -> Proxy a -> b -> s -> t`

- Changed order of arguments of functions
`set`

and`set'`

(**breaking change**):`set :: Setter s t b -> b -> s -> t`

`set' :: Setter' s a -> a -> s -> s`

- Introduced type family
`R`

that can be used to define more compact type signatures when mentioning multiple record fields in it. (**new**) - Uploaded to Hackage: http://hackage.haskell.org/package/overloaded-records-0.4.0.0

## Version 0.3.0.0

- Fixed defaultMakeFieldName, which actually behaved correctly only in very few
cases. (
**bug fix**) - Added missing
`HAVE_OVERLOADED_LABELS`

macro, that actually allows us to use GHC’s`IsLabel`

on GHC >8. (**bug fix**) - Exposing previously hidden
`FromArrow`

and`IsFieldAccessor`

. (**change**) - Few simple unit tests. (
**new**) - Uploaded to Hackage: http://hackage.haskell.org/package/overloaded-records-0.3.0.0

## Version 0.2.0.0

- Function
`overloadedRecords`

renamed to`overloadedRecord`

. There is also new`overloadedRecords`

function, that behaves as`overloadedRecord`

, but for multiple types at once. (**breaking change**) - It is now possible to customize overloadedRecord* family of functions with
custom getter and setter implementation. (
**new**) - Types and functions follow, hopefully, better naming conventions. (
**change**) - More low-level template haskell functions for those cases when it is
necessary to build your own higher-level ones, or when you need much more
control over the result. (
**new**) - Uploaded to Hackage: http://hackage.haskell.org/package/overloaded-records-0.2.0.0

## Version 0.1.0.0

- First public release.
- Uploaded to Hackage: http://hackage.haskell.org/package/overloaded-records-0.1.0.0

*(full list with versions)*: