-- | -- This module provides accessors and modifiers for labeled -- records. As the module name indicates, the functions -- provided by this module are designed to work with records -- under the following conditions: -- -- (1) The 'TaggedFunctor' is parameterized by 'Identity'. -- (2) The @VisibleTypeApplication@ extension is unavailable. -- module Data.Vinyl.Optic.Tagged.Proxy.Identity ( -- * Functions lens , get , set , modify -- * Tutorial -- $tutorial ) where -- import Data.Coerce import Data.Functor.Identity (Identity (..)) import Data.Tagged.Functor (TaggedFunctor) import Data.Vinyl.Core (Rec) import Data.Vinyl.Optic.Tagged.Class import GHC.Prim (Proxy#, proxy#) lens :: forall k g rs i v proxy. (Functor g, IxElem k rs i v) => proxy k -> (v -> g v) -> Rec (TaggedFunctor Identity) rs -> g (Rec (TaggedFunctor Identity) rs) lens _ conv = rlensBy' (proxy# :: Proxy# k) (fmap Identity . conv . runIdentity) get :: forall k rs i v proxy. IxElem k rs i v => proxy k -> Rec (TaggedFunctor Identity) rs -> v get _ rec = runIdentity (rgetBy' (proxy# :: Proxy# k) rec) set :: forall k rs i v proxy. IxElem k rs i v => proxy k -> v -> Rec (TaggedFunctor Identity) rs -> Rec (TaggedFunctor Identity) rs set _ newVal rec = rsetBy' (proxy# :: Proxy# k) (Identity newVal) rec modify :: forall k rs i v proxy. IxElem k rs i v => proxy k -> (v -> v) -> Rec (TaggedFunctor Identity) rs -> Rec (TaggedFunctor Identity) rs modify _ f rec = rmodifyBy' (proxy# :: Proxy# k) (Identity . f . runIdentity) rec {- $tutorial Here is a explanation of how the functions in this module can be used. First we will create a record: >>> import Data.Tagged.Functor >>> import Data.Functor.Identity >>> import Data.Proxy >>> import Data.Vinyl.Core >>> :{ let person = tagIdentity (Proxy :: Proxy "age") (44 :: Int) :& tagIdentity (Proxy :: Proxy "name") ("Alexa" :: String) :& tagIdentity (Proxy :: Proxy "alive") True :& RNil :} Notice that the type of @person@ is inferred and fully monomorphic: >>> :t person person :: Rec (TaggedFunctor Identity) '['("age", Int), '("name", String), '("alive", Bool)] The 'Identity' wrappers are cumbersome to deal with. This module provides extra functions (suffixed with @Id@) that get eliminate some of the boilerplate. With these functions, the above becomes: >>> get (Proxy :: Proxy "name") person "Alexa" >>> let deceased2 = set (Proxy :: Proxy "alive") False person >>> get (Proxy :: Proxy "alive") deceased2 False >>> let older2 = modify (Proxy :: Proxy "age") (+12) person >>> get (Proxy :: Proxy "age") older2 56 -}