generic-lens-2.2.2.0: Generically derive traversals, lenses and prisms.

Copyright | (C) 2020 Csongor Kiss
License | BSD3
Maintainer | Csongor Kiss <kiss.csongor.kiss@gmail.com>
Stability | experimental
Portability | non-portable
Safe Haskell | None
Language | Haskell2010

Data.Generics.Product.Fields

Contents

- Lenses

Description

Derive record field getters and setters generically.

Synopsis

- class HasField (field :: Symbol) s t a b | s field -> a, t field -> b, s field b -> t, t field a -> s where
  - field :: Lens s t a b
- class HasField' (field :: Symbol) s a | s field -> a where
  - field' :: Lens s s a a
- class HasField_ (field :: Symbol) s t a b where
  - field_ :: Lens s t a b
- getField :: forall (f :: Symbol) a s. HasField' f s a => s -> a
- setField :: forall (f :: Symbol) s a. HasField' f s a => a -> s -> s

# Lenses

## Running example:

    >>> :set -XTypeApplications
    >>> :set -XDataKinds
    >>> :set -XDeriveGeneric
    >>> :set -XGADTs
    >>> :set -XFlexibleContexts
    >>> import GHC.Generics
    >>> :m +Data.Generics.Internal.VL.Lens
    >>> :m +Data.Function
    >>> :{
    data Human a
      = Human
        { name    :: String
        , age     :: Int
        , address :: String
        , other   :: a
        }
      | HumanNoAddress
        { name    :: String
        , age     :: Int
        , other   :: a
        }
      deriving (Generic, Show)
    human :: Human Bool
    human = Human { name = "Tunyasz", age = 50, address = "London", other = False }
    :}

class HasField (field :: Symbol) s t a b | s field -> a, t field -> b, s field b -> t, t field a -> s where Source #

Records that have a field with a given name.

Methods

field :: Lens s t a b Source #

A lens that focuses on a field with a given name. Compatible with the lens package's `Lens` type.

    >>> human ^. field @"age"
    50

### Type changing

    >>> :t human
    human :: Human Bool

    >>> :t human & field @"other" .~ (42 :: Int)
    human & field @"other" .~ (42 :: Int) :: Human Int

    >>> human & field @"other" .~ 42
    Human {name = "Tunyasz", age = 50, address = "London", other = 42}

### Type errors

    >>> human & field @"weight" .~ 42
    ...
    ... The type Human Bool does not contain a field named 'weight'.
    ...

    >>> human & field @"address" .~ ""
    ...
    ... Not all constructors of the type Human Bool
    ... contain a field named 'address'.
    ... The offending constructors are:
    ... HumanNoAddress
    ...

#### Instances

Instances details

(Context field s t a b, HasField0 field s t a b) => HasField field s t a b Source # |
Instance details Defined in Data.Generics.Product.Fields Methods field :: Lens s t a b Source #

HasField f (Void1 a) (Void1 b) a b Source #

Uncluttering type signatures (see `Void`)

    >>> :t +d field
    field
      :: (HasField field s t a b, Functor f) => (a -> f b) -> s -> f t

Instance details Defined in Data.Generics.Product.Fields Methods field :: Lens (Void1 a) (Void1 b) a b Source #

class HasField' (field :: Symbol) s a | s field -> a where Source #

Methods

field' :: Lens s s a a Source #

#### Instances

Instances details

Context' field s a => HasField' field s a Source # |
Instance details Defined in Data.Generics.Product.Fields Methods field' :: Lens s s a a Source #
HasField' f (Void1 a) a Source # |
Instance details Defined in Data.Generics.Product.Fields Methods field' :: Lens (Void1 a) (Void1 a) a a Source #

class HasField_ (field :: Symbol) s t a b where Source #

Records that have a field with a given name.

This is meant to be more general than `HasField`, but that is not quite the case due to the lack of functional dependencies.

The types `s` and `t` must be applications of the same type constructor. In contrast, `HasField` also requires the parameters of that type constructor to have representational roles.

One use case of `HasField_` over `HasField` is for records defined with `data instance`.

Methods

field_ :: Lens s t a b Source #

#### Instances

Instances details

(Context_ field s t a b, HasField0 field s t a b) => HasField_ field s t a b Source # |
Instance details Defined in Data.Generics.Product.Fields Methods field_ :: Lens s t a b Source #
HasField_ f (Void1 a) (Void1 b) a b Source # |
Instance details Defined in Data.Generics.Product.Fields Methods field_ :: Lens (Void1 a) (Void1 b) a b Source #

getField :: forall (f :: Symbol) a s. HasField' f s a => s -> a Source #

    >>> getField @"age" human
    50

setField :: forall (f :: Symbol) s a. HasField' f s a => a -> s -> s Source #

    >>> setField @"age" 60 human
    Human {name = "Tunyasz", age = 60, address = "London", other = False}