@@ -0,0 +1,75 @@
1+{-# LANGUAGE AllowAmbiguousTypes #-}
2+{-# LANGUAGE FlexibleInstances #-}
3+{-# LANGUAGE FunctionalDependencies #-}
4+{-# LANGUAGE MultiParamTypeClasses #-}
5+{-# LANGUAGE PolyKinds #-}
6+{-# LANGUAGE ScopedTypeVariables #-}
7+{-# LANGUAGE TypeApplications #-}
8+{-# LANGUAGE UndecidableInstances #-}
9+
10+-----------------------------------------------------------------------------
11+-- |
12+-- Module : Data.Generics.Record.HasField
13+-- Copyright : (C) 2017 Csongor Kiss
14+-- License : BSD3
15+-- Maintainer : Csongor Kiss <kiss.csongor.kiss@gmail.com>
16+-- Stability : experimental
17+-- Portability : non-portable
18+--
19+-- Derive a variety of record lenses generically.
20+--
21+-----------------------------------------------------------------------------
22+
23+module Data.Generics.Product.Any
24+ ( -- * Lenses
25+ --
26+ -- $example
27+ HasAny (..)
28+ ) where
29+
30+import Data.Generics.Internal.Lens
31+import Data.Generics.Product.Fields
32+import Data.Generics.Product.Numbered
33+import Data.Generics.Product.Typed
34+
35+-- $example
36+-- @
37+-- module Example where
38+--
39+-- import Data.Generics.Product
40+-- import GHC.Generics
41+--
42+-- data Human = Human
43+-- { name :: String
44+-- , age :: Int
45+-- , address :: String
46+-- }
47+-- deriving (Generic, Show)
48+--
49+-- human :: Human
50+-- human = Human \"Tunyasz\" 50 \"London\"
51+-- @
52+
53+-- | Records that have generic lenses.
54+class HasAny (sel :: k) a s | s sel k -> a where
55+ -- | A lens that focuses on a part of a product as identified by some
56+ -- selector. Currently supported selectors are field names, positions and
57+ -- unique types. Compatible with the lens package's 'Control.Lens.Lens'
58+ -- type.
59+ --
60+ -- >>> human ^. its @Int
61+ -- 50
62+ -- >>> human ^. its @"name"
63+ -- "Tunyasz"
64+ -- >>> human ^. its @3
65+ -- "London"
66+ its :: Lens' s a
67+
68+instance HasPosition i a s => HasAny i a s where
69+ its = numbered @i
70+
71+instance HasField field a s => HasAny field a s where
72+ its = field @field
73+
74+instance HasType a s => HasAny a a s where
75+ its = typed @a