1{-# LANGUAGE AllowAmbiguousTypes #-}
2{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE FunctionalDependencies #-}
5{-# LANGUAGE KindSignatures #-}
6{-# LANGUAGE MultiParamTypeClasses #-}
7{-# LANGUAGE ScopedTypeVariables #-}
8{-# LANGUAGE TypeApplications #-}
9{-# LANGUAGE TypeFamilies #-}
10{-# LANGUAGE TypeOperators #-}
11{-# LANGUAGE UndecidableInstances #-}
13-----------------------------------------------------------------------------
15-- Module : Data.Generics.Product.Fields
16-- Copyright : (C) 2017 Csongor Kiss
18-- Maintainer : Csongor Kiss <kiss.csongor.kiss@gmail.com>
19-- Stability : experimental
20-- Portability : non-portable
22-- Derive record field getters and setters generically.
24-----------------------------------------------------------------------------
26module Data.Generics.Product.Fields
33import Data.Generics.Internal.Families
34import Data.Generics.Internal.Lens
35import Data.Generics.Product.Internal.Fields
37import Data.Kind (Constraint, Type)
39import GHC.TypeLits (Symbol, ErrorMessage(..), TypeError)
43-- module Example where
45-- import Data.Generics.Product
53-- deriving (Generic, Show)
56-- human = Human \"Tunyasz\" 50 \"London\"
59-- |Records that have a field with a given name.
60class HasField (field :: Symbol) a s | s field -> a where
61 -- |A lens that focuses on a field with a given name. Compatible with the
62 -- lens package's 'Control.Lens.Lens' type.
64 -- >>> human ^. field @"age"
66 -- >>> human & field @"name" .~ "Tamas"
67 -- Human {name = "Tamas", age = 50, address = "London"}
70 = fmap (flip (setField @field) s) (f (getField @field s))
74 -- >>> getField @"name" human
77 getField s = s ^. field @field
81 -- >>> setField @"age" (setField @"name" "Tamas" human) 30
82 -- Human {name = "Tamas", age = 30, address = "London"}
83 setField :: a -> s -> s
84 setField = set (field @field)
86 {-# MINIMAL field | setField, getField #-}
90 , ErrorUnless field s (HasTotalFieldP field (Rep s))
91 , GHasField field (Rep s) a
92 ) => HasField field a s where
94 field = repIso . gfield @field
96type family ErrorUnless (field :: Symbol) (s :: Type) (contains :: Bool) :: Constraint where
97 ErrorUnless field s 'False
101 ':<>: 'Text " does not contain a field named "
102 ':<>: 'ShowType field
105 ErrorUnless _ _ 'True
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list