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.Types

Contents

- Traversals
- Custom traversal strategies

Description

Derive traversals of a given type in a product.

Synopsis

- class HasTypes s a
- types :: forall a s. HasTypes s a => Traversal' s a
- type family Children ch a :: [Type]
- data ChGeneric
- class HasTypesUsing ch s t a b
- typesUsing :: forall ch a s. HasTypesUsing ch s s a a => Traversal' s a
- class HasTypesCustom ch s t a b where
  - typesCustom :: Traversal s t a b

# Traversals

## Running example:

    >>> :set -XTypeApplications
    >>> :set -XDeriveGeneric
    >>> :set -XScopedTypeVariables
    >>> import GHC.Generics
    >>> :m +Data.Generics.Internal.VL.Traversal
    >>> :m +Data.Generics.Internal.VL.Lens
    >>> :{
    data WTree a w
      = Leaf a
      | Fork (WTree a w) (WTree a w)
      | WithWeight (WTree a w) w
      deriving (Generic, Show)
    :}

class HasTypes s a Source #

#### Instances

Instances details

HasTypes Void a |
Instance details Defined in Data.Generics.Product.Internal.Types Methods types_ :: Traversal' Void a Source #
HasTypes s Void |
Instance details Defined in Data.Generics.Product.Internal.Types Methods types_ :: Traversal' s Void Source #
HasTypesUsing ChGeneric s s a a => HasTypes s a |
Instance details Defined in Data.Generics.Product.Internal.Types Methods types_ :: Traversal' s a Source #

types :: forall a s. HasTypes s a => Traversal' s a Source #

Traverse all types in the given structure.

For example, to update all `String`s in a `WTree (Maybe String) String`, we can write

    >>> myTree = WithWeight (Fork (Leaf (Just "hello")) (Leaf Nothing)) "world"
    >>> over (types @String) (++ "!") myTree
    WithWeight (Fork (Leaf (Just "hello!")) (Leaf Nothing)) "world!"

The traversal is deep, which means that not just the immediate children are visited, but all nested values too.

# Custom traversal strategies

The default traversal strategy `types` recurses into each node of the type using the `Generic` instance for the nodes. However, in general not all nodes will have a `Generic` instance. For example:

    >>> data Opaque = Opaque String deriving Show
    >>> myTree = WithWeight (Fork (Leaf (Opaque "foo")) (Leaf (Opaque "bar"))) False
    >>> over (types @String) (++ "!") myTree
    ...
    ... | No instance for ‘Generic Opaque’
    ... |   arising from a generic traversal.
    ... |   Either derive the instance, or define a custom traversal using HasTypesCustom
    ...

In these cases, we can define a custom traversal strategy to override the generic behaviour for certain types. For a self-contained example, see the CustomChildren module in the tests directory.

type family Children ch a :: [Type] Source #

The children of a type are the types of its fields. The `Children` type family maps a type `a` to its set of children.

This type family is parameterized by a symbol `ch` (that can be declared as an empty data type). The symbol `ChGeneric` provides a default definition. You can create new symbols to override the set of children of abstract, non-generic types.

The following example declares a `Custom` symbol to redefine `Children` for some abstract types from the `time` library.

    data Custom
    type instance Children Custom a = ChildrenCustom a

    type family ChildrenCustom (a :: Type) where
      ChildrenCustom DiffTime        = '[]
      ChildrenCustom NominalDiffTime = '[]
      -- Add more custom mappings here.

      ChildrenCustom a = Children ChGeneric a

To use this definition, replace `types` with ``typesUsing` @Custom`.

#### Instances

Instances details

type Children ChGeneric a |
Instance details Defined in Data.Generics.Product.Internal.Types type Children ChGeneric a = ChildrenDefault a

data ChGeneric Source #

The default definition of `Children`. Primitive types from core libraries have no children, and other types are assumed to be `Generic`.

#### Instances

Instances details

HasTypes b a => GHasTypes ChGeneric (Rec0 b :: k -> Type) (Rec0 b :: k -> Type) a a

The default instance for `HasTypes` acts as a synonym for 'HasTypesUsing ChGeneric', so in most cases this instance should behave the same as the one above. However, there might be overlapping instances defined for `HasTypes` directly, in which case we want to prefer those instances (even though the custom instances should always be added to `HasTypesCustom`)

Instance details Defined in Data.Generics.Product.Internal.Types Methods gtypes_ :: forall (x :: k). Traversal (Rec0 b x) (Rec0 b x) a a Source #
type Children ChGeneric a |
Instance details Defined in Data.Generics.Product.Internal.Types type Children ChGeneric a = ChildrenDefault a

class HasTypesUsing ch s t a b Source #

Since: generic-lens-core-1.2.0.0

Minimal complete definition

typesUsing_

#### Instances

Instances details

HasTypesUsing ch Void Void a b |
Instance details Defined in Data.Generics.Product.Internal.Types Methods typesUsing_ :: Traversal Void Void a b Source #
HasTypesUsing ch a b a b |
Instance details Defined in Data.Generics.Product.Internal.Types Methods typesUsing_ :: Traversal a b a b Source #
HasTypesUsing ch s s Void Void |
Instance details Defined in Data.Generics.Product.Internal.Types Methods typesUsing_ :: Traversal s s Void Void Source #
HasTypesOpt ch (Interesting ch a s) s t a b => HasTypesUsing ch s t a b |
Instance details Defined in Data.Generics.Product.Internal.Types Methods typesUsing_ :: Traversal s t a b Source #

typesUsing :: forall ch a s. HasTypesUsing ch s s a a => Traversal' s a Source #

Since: 1.2.0.0

class HasTypesCustom ch s t a b where Source #

By adding instances to this class, we can override the default behaviour in an ad-hoc manner. For example:

    instance HasTypesCustom Custom Opaque Opaque String String where
      typesCustom f (Opaque str) = Opaque $ f str

Since: generic-lens-core-1.2.0.0

Methods

typesCustom :: Traversal s t a b Source #

This function should never be used directly, only to override the default traversal behaviour. To actually use the custom traversal strategy, see `typesUsing`. This is because `typesUsing` does additional optimisations, like ensuring that nodes with no relevant members will not be traversed at runtime.

#### Instances

Instances details

(GHasTypes ch (Rep s) (Rep t) a b, Generic s, Generic t, Defined (Rep s) (PrettyError '['Text "No instance " ':<>: QuoteType (HasTypesCustom ch s t a b)] :: Constraint) ()) => HasTypesCustom ch s t a b |
Instance details Defined in Data.Generics.Product.Internal.Types Methods typesCustom :: Traversal s t a b Source #