{- | An implementation of overloaded record fields. This module enables different types in the same module to have fields of the same name. To use instances from this class, either: * Enable the @OverloadedLabels@ extension and @import Data.ProtoLens.Labels ()@; * Use the 'field' function along with the @TypeApplications@ extension; or, * Import the corresponding names from the autogenerated @*_Fields@ module. For more information, see . -} {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE ScopedTypeVariables #-} module Data.ProtoLens.Field ( HasField(..) , field ) where import GHC.Prim (Proxy#, proxy#) import GHC.TypeLits (Symbol) -- | A lens for a given field. For example: -- -- > view field@"abc" x -- > set field@"abc" 42 x field :: forall x s a f . (HasField s x a, Functor f) => (a -> f a) -> s -> f s field = fieldOf (proxy# :: Proxy# x) -- | A type class for lens fields. -- -- The instance @HasField s x a@ can be understood as "@s@ has a field named @x@ -- of type @a@". class HasField s (x :: Symbol) a | s x -> a where fieldOf :: Functor f => Proxy# x -> (a -> f a) -> s -> f s