HList-0.5.0.0: Heterogeneous lists

Safe HaskellNone
LanguageHaskell2010

Data.HList.Labelable

Contents

Description

A simple problem is being solved here, but unfortunately it is a bit involved. The idea is to use the same haskell identifier for a lens and for other purposes. In other words, get the same behavior as:

x = hLens (Label :: Label "x")
r ^. x

While still being able to extract the symbol "x" from x, so that things like x .=. 123 could be acceptable. In this case we don't overload .=., so instead you have to write x .==. 123.

Elaboration of some ideas from edwardk.

Synopsis

Documentation

class SameLength s t => Labelable (x :: k) (r :: [*] -> *) s t a b | x s -> a, x t -> b, x s b -> t, x t a -> s where Source #

r
is Record, Variant. TIP and TIC also have instances, but generally tipyLens' and ticPrism' are more appropriate.
x
is the label for the field. It tends to have kind Symbol, but others are supported in principle.

Minimal complete definition

hLens'

Associated Types

type LabelableTy r :: LabeledOpticType Source #

Methods

hLens' :: Label x -> LabeledOptic x r s t a b Source #

Instances

LabelableTIPCxt k x s t a b => Labelable k x TIP s t a b Source #

make a Lens' (TIP s) a.

tipyLens provides a Lens (TIP s) (TIP t) a b, which tends to need too many type annotations to be practical

Associated Types

type LabelableTy (s :: [*] -> *) :: LabeledOpticType Source #

Methods

hLens' :: Label x TIP -> LabeledOptic x TIP s t a b b Source #

(TICPrism s t a b, (~) * (Label k x) (Label * a), (~) * a b, (~) [*] s t, SameLength * * s t) => Labelable k x TIC s t a b Source #
hLens' :: Label a -> Prism' (TIC s) a

note that a more general function ticPrism :: Prism (TIC s) (TIC t) a b, cannot have an instance of Labelable

Note: `x :: k` according to the instance head, but the instance body forces the kind variable to be * later on. IE. (k ~ *)

Associated Types

type LabelableTy (s :: [*] -> *) :: LabeledOpticType Source #

Methods

hLens' :: Label x TIC -> LabeledOptic x TIC s t a b b Source #

(HPrism k x s t a b, (~) (* -> * -> *) to ((->) LiftedRep LiftedRep)) => Labelable k x Variant s t a b Source #

make a Prism (Variant s) (Variant t) a b

Associated Types

type LabelableTy (s :: [*] -> *) :: LabeledOpticType Source #

Methods

hLens' :: Label x Variant -> LabeledOptic x Variant s t a b b Source #

HLens k x Record s t a b => Labelable k x Record s t a b Source #

make a Lens (Record s) (Record t) a b

Associated Types

type LabelableTy (s :: [*] -> *) :: LabeledOpticType Source #

Methods

hLens' :: Label x Record -> LabeledOptic x Record s t a b b Source #

LabeledCxt1 * * s t a b => Labelable k x LabeledR s t a b Source #

used with toLabel and/or .==.

Associated Types

type LabelableTy (s :: [*] -> *) :: LabeledOpticType Source #

Methods

hLens' :: Label x LabeledR -> LabeledOptic x LabeledR s t a b b Source #

((~) [*] s t, (~) * a b, IArray UArray a, (~) * a (GetElemTy s), HLensCxt k x RecordU s t a b) => Labelable k x RecordU s t a b Source #

make a Lens' (RecordU s) a

Associated Types

type LabelableTy (s :: [*] -> *) :: LabeledOpticType Source #

Methods

hLens' :: Label x RecordU -> LabeledOptic x RecordU s t a b b Source #

type LabeledOptic (x :: k) (r :: [*] -> *) (s :: [*]) (t :: [*]) (a :: *) (b :: *) = forall ty to p f. (ty ~ LabelableTy r, LabeledOpticF ty f, LabeledOpticP ty p, LabeledOpticTo ty x to) => (a `p` f b) `to` (r s `p` f (r t)) Source #

This alias is the same as Control.Lens.Optic, except the (->) in Optic is a type parameter to in LabeledOptic.

Depending on the collection type (see instances of LabelableTy), the type variables to, p, f are constrained such that the resulting type is a Lens (r s) (r t) a b, Prism (r s) (r t) a b or a LabeledTo x _ _. The latter can be used to recover the label (x) when used as an argument to .==. or equivalently toLabel.

(.==.) :: EnsureLabel x (Label k l) => x -> v -> Tagged k l v infixr 4 Source #

modification of .=. which works with the labels from this module, and those from Data.HList.Label6. Note that this is not strictly a generalization of .=., since it does not work with labels like Data.HList.Label3 which have the wrong kind.

multiple lookups

class Projected r s t a b where Source #

Sometimes it may be more convenient to operate on a record/variant that only contains the fields of interest. projected can then be used to apply that function to a record that contains additional elements.

>>> :set -XViewPatterns
>>> import Data.HList.RecordPuns
>>> let f [pun| (x y) |] = case x+y of z -> [pun| z |]
>>> :t f
f :: Num v =>
     Record '[Tagged "x" v, Tagged "y" v] -> Record '[Tagged "z" v]
>>> let r = (let x = 1; y = 2; z = () in [pun| x y z |])
>>> r
Record{x=1,y=2,z=()}
>>> r & sameLabels . projected %~ f
Record{x=1,y=2,z=3}

Minimal complete definition

projected

Methods

projected :: (ty ~ LabelableTy r, LabeledOpticP ty p, LabeledOpticF ty f) => (r a `p` f (r b)) -> r s `p` f (r t) Source #

Instances

(H2ProjectByLabels (LabelsOf a) s a_ _s_minus_a, HRLabelSet a_, HRLabelSet a, HRearrange (LabelsOf a) a_ a, HLeftUnion b s bs, HRLabelSet bs, HRearrange (LabelsOf t) bs t, HRLabelSet t) => Projected Record s t a b Source #
Lens rs rt ra rb

where rs ~ Record s, rt ~ Record t, ra ~ Record a, rb ~ Record b

Methods

projected :: ((LabeledOpticType ~ ty) (LabelableTy Record), LabeledOpticP ty p, LabeledOpticF ty f) => p (Record a) (f (Record b)) -> p (Record s) (f (Record t)) Source #

(ExtendsVariant b t, ProjectVariant s a, ProjectExtendVariant s t, HLeftUnion b s bs, HRLabelSet bs, HRearrange (LabelsOf t) bs t) => Projected Variant s t a b Source #
Prism (Variant s) (Variant t) (Variant a) (Variant b)

Methods

projected :: ((LabeledOpticType ~ ty) (LabelableTy Variant), LabeledOpticP ty p, LabeledOpticF ty f) => p (Variant a) (f (Variant b)) -> p (Variant s) (f (Variant t)) Source #

projected' :: (Projected r t t b b, LabeledOpticF (LabelableTy r) f, LabeledOpticP (LabelableTy r) p) => p (r b) (f (r b)) -> p (r t) (f (r t)) Source #

Lens' (Record s) (Record a)
Prism' (Variant s) (Variant a)

comparison with hLens

Note that passing around variables defined with hLens' doesn't get you exactly the same thing as calling hLens at the call-site:

The following code needs to apply the x for different Functor f =>, so you would have to write a type signature (rank-2) to allow this definition:

-- with the x defined using hLens'
let f x r = let
         a = r ^. x
         b = r & x .~ "6"
       in (a,b)

This alternative won't need a type signature

-- with the x defined as x = Label :: Label "x"
let f x r = let
         a = r ^. hLens x
         b = r & hLens x .~ "6"
       in (a,b)

It may work to use hLens' instead of hLens in the second code, but that is a bit beside the point being made here.

The same points apply to the use of hPrism over hLens'.

likely unneeded (re)exports

type LabeledCxt1 s t a b = (s ~ '[], t ~ '[], a ~ (), b ~ ()) Source #

sets all type variables to dummy values: only the Labeled x part is actually needed

data LabeledTo (x :: k) (a :: *) (b :: *) Source #

Constructors

LabeledTo 

Instances

Show (LabeledTo k x a b) Source # 

Methods

showsPrec :: Int -> LabeledTo k x a b -> ShowS #

show :: LabeledTo k x a b -> String #

showList :: [LabeledTo k x a b] -> ShowS #

data LabeledR (x :: [*]) Source #

Constructors

LabeledR 

Instances

LabeledCxt1 * * s t a b => Labelable k x LabeledR s t a b Source #

used with toLabel and/or .==.

Associated Types

type LabelableTy (s :: [*] -> *) :: LabeledOpticType Source #

Methods

hLens' :: Label x LabeledR -> LabeledOptic x LabeledR s t a b b Source #

type LabelableTy LabeledR Source # 

class ToSym label (s :: Symbol) | label -> s Source #

Get the Symbol out of a Label or LabeledTo

Instances

ToSym k (label x) x Source # 
(~) * (LabeledTo Symbol x (p a (f b)) (p (LabeledR s) (f (LabeledR t)))) (v1 v2 v3) => ToSym * (v1 v2 v3) x Source # 

class EnsureLabel x y | x -> y where Source #

Convert a type to Label :: Label blah

toLabel :: LabeledTo x _ _ -> Label (x :: Symbol)
toLabel (hLens' lx)         = (lx :: Label x)
toLabel :: Label x         -> Label x
toLabel :: Proxy x         -> Label x

Minimal complete definition

toLabel

Methods

toLabel :: x -> y Source #

Instances

ToSym * (a b c) x => EnsureLabel (a b c) (Label Symbol x) Source #

get the Label out of a LabeledTo (ie. `foobar when using HListPP).

Methods

toLabel :: a b c -> Label Symbol x Source #

EnsureLabel (Proxy k x) (Label k x) Source # 

Methods

toLabel :: Proxy k x -> Label k x Source #

EnsureLabel (Label k x) (Label k x) Source # 

Methods

toLabel :: Label k x -> Label k x Source #

toLabelSym :: EnsureLabel x1 (Label Symbol x2) => x1 -> Label Symbol x2 Source #

fix the k kind variable to Symbol

data Identity a :: * -> * #

Identity functor and monad. (a non-strict monad)

Since: 4.8.0.0

Instances

Monad Identity

Since: 4.8.0.0

Methods

(>>=) :: Identity a -> (a -> Identity b) -> Identity b #

(>>) :: Identity a -> Identity b -> Identity b #

return :: a -> Identity a #

fail :: String -> Identity a #

Functor Identity

Since: 4.8.0.0

Methods

fmap :: (a -> b) -> Identity a -> Identity b #

(<$) :: a -> Identity b -> Identity a #

MonadFix Identity

Since: 4.8.0.0

Methods

mfix :: (a -> Identity a) -> Identity a #

Applicative Identity

Since: 4.8.0.0

Methods

pure :: a -> Identity a #

(<*>) :: Identity (a -> b) -> Identity a -> Identity b #

liftA2 :: (a -> b -> c) -> Identity a -> Identity b -> Identity c #

(*>) :: Identity a -> Identity b -> Identity b #

(<*) :: Identity a -> Identity b -> Identity a #

Foldable Identity

Since: 4.8.0.0

Methods

fold :: Monoid m => Identity m -> m #

foldMap :: Monoid m => (a -> m) -> Identity a -> m #

foldr :: (a -> b -> b) -> b -> Identity a -> b #

foldr' :: (a -> b -> b) -> b -> Identity a -> b #

foldl :: (b -> a -> b) -> b -> Identity a -> b #

foldl' :: (b -> a -> b) -> b -> Identity a -> b #

foldr1 :: (a -> a -> a) -> Identity a -> a #

foldl1 :: (a -> a -> a) -> Identity a -> a #

toList :: Identity a -> [a] #

null :: Identity a -> Bool #

length :: Identity a -> Int #

elem :: Eq a => a -> Identity a -> Bool #

maximum :: Ord a => Identity a -> a #

minimum :: Ord a => Identity a -> a #

sum :: Num a => Identity a -> a #

product :: Num a => Identity a -> a #

Traversable Identity 

Methods

traverse :: Applicative f => (a -> f b) -> Identity a -> f (Identity b) #

sequenceA :: Applicative f => Identity (f a) -> f (Identity a) #

mapM :: Monad m => (a -> m b) -> Identity a -> m (Identity b) #

sequence :: Monad m => Identity (m a) -> m (Identity a) #

Comonad Identity 

Methods

extract :: Identity a -> a #

duplicate :: Identity a -> Identity (Identity a) #

extend :: (Identity a -> b) -> Identity a -> Identity b #

ComonadApply Identity 

Methods

(<@>) :: Identity (a -> b) -> Identity a -> Identity b #

(@>) :: Identity a -> Identity b -> Identity b #

(<@) :: Identity a -> Identity b -> Identity a #

Bounded a => Bounded (Identity a) 
Enum a => Enum (Identity a) 
Eq a => Eq (Identity a) 

Methods

(==) :: Identity a -> Identity a -> Bool #

(/=) :: Identity a -> Identity a -> Bool #

Floating a => Floating (Identity a) 
Fractional a => Fractional (Identity a) 
Integral a => Integral (Identity a) 
Data a => Data (Identity a)

Since: 4.9.0.0

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Identity a -> c (Identity a) #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Identity a) #

toConstr :: Identity a -> Constr #

dataTypeOf :: Identity a -> DataType #

dataCast1 :: Typeable (* -> *) t => (forall d. Data d => c (t d)) -> Maybe (c (Identity a)) #

dataCast2 :: Typeable (* -> * -> *) t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Identity a)) #

gmapT :: (forall b. Data b => b -> b) -> Identity a -> Identity a #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Identity a -> r #

gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Identity a -> r #

gmapQ :: (forall d. Data d => d -> u) -> Identity a -> [u] #

gmapQi :: Int -> (forall d. Data d => d -> u) -> Identity a -> u #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> Identity a -> m (Identity a) #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Identity a -> m (Identity a) #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Identity a -> m (Identity a) #

Num a => Num (Identity a) 
Ord a => Ord (Identity a) 

Methods

compare :: Identity a -> Identity a -> Ordering #

(<) :: Identity a -> Identity a -> Bool #

(<=) :: Identity a -> Identity a -> Bool #

(>) :: Identity a -> Identity a -> Bool #

(>=) :: Identity a -> Identity a -> Bool #

max :: Identity a -> Identity a -> Identity a #

min :: Identity a -> Identity a -> Identity a #

Read a => Read (Identity a)

This instance would be equivalent to the derived instances of the Identity newtype if the runIdentity field were removed

Since: 4.8.0.0

Real a => Real (Identity a) 

Methods

toRational :: Identity a -> Rational #

RealFloat a => RealFloat (Identity a) 
RealFrac a => RealFrac (Identity a) 

Methods

properFraction :: Integral b => Identity a -> (b, Identity a) #

truncate :: Integral b => Identity a -> b #

round :: Integral b => Identity a -> b #

ceiling :: Integral b => Identity a -> b #

floor :: Integral b => Identity a -> b #

Show a => Show (Identity a)

This instance would be equivalent to the derived instances of the Identity newtype if the runIdentity field were removed

Since: 4.8.0.0

Methods

showsPrec :: Int -> Identity a -> ShowS #

show :: Identity a -> String #

showList :: [Identity a] -> ShowS #

Ix a => Ix (Identity a) 
Generic (Identity a) 

Associated Types

type Rep (Identity a) :: * -> * #

Methods

from :: Identity a -> Rep (Identity a) x #

to :: Rep (Identity a) x -> Identity a #

Semigroup a => Semigroup (Identity a)

Since: 4.9.0.0

Methods

(<>) :: Identity a -> Identity a -> Identity a #

sconcat :: NonEmpty (Identity a) -> Identity a #

stimes :: Integral b => b -> Identity a -> Identity a #

Monoid a => Monoid (Identity a) 

Methods

mempty :: Identity a #

mappend :: Identity a -> Identity a -> Identity a #

mconcat :: [Identity a] -> Identity a #

Storable a => Storable (Identity a) 

Methods

sizeOf :: Identity a -> Int #

alignment :: Identity a -> Int #

peekElemOff :: Ptr (Identity a) -> Int -> IO (Identity a) #

pokeElemOff :: Ptr (Identity a) -> Int -> Identity a -> IO () #

peekByteOff :: Ptr b -> Int -> IO (Identity a) #

pokeByteOff :: Ptr b -> Int -> Identity a -> IO () #

peek :: Ptr (Identity a) -> IO (Identity a) #

poke :: Ptr (Identity a) -> Identity a -> IO () #

Bits a => Bits (Identity a) 
FiniteBits a => FiniteBits (Identity a) 
Generic1 * Identity 

Associated Types

type Rep1 Identity (f :: Identity -> *) :: k -> * #

Methods

from1 :: f a -> Rep1 Identity f a #

to1 :: Rep1 Identity f a -> f a #

type Rep (Identity a) 
type Rep (Identity a) = D1 * (MetaData "Identity" "Data.Functor.Identity" "base" True) (C1 * (MetaCons "Identity" PrefixI True) (S1 * (MetaSel (Just Symbol "runIdentity") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 * a)))
type Rep1 * Identity 
type Rep1 * Identity = D1 * (MetaData "Identity" "Data.Functor.Identity" "base" True) (C1 * (MetaCons "Identity" PrefixI True) (S1 * (MetaSel (Just Symbol "runIdentity") NoSourceUnpackedness NoSourceStrictness DecidedLazy) Par1))

type LabelableTIPCxt x s t a b = (s ~ t, a ~ b, Label x ~ Label a, HLens x TIP s t a b) Source #

type family LabeledOpticTo (ty :: LabeledOpticType) (x :: k) :: (* -> * -> *) -> Constraint Source #

Orphan instances

((~) (* -> * -> *) to (LabeledTo Symbol x), ToSym * (to p q) x) => HExtend (to p q) (Proxy [*] ((:) * (Lbl n ns desc) xs)) Source #

if the proxy has Data.HList.Label3.Lbl, then everything has to be wrapped in Label to make the kinds match up.

Associated Types

type HExtendR (to p q) (Proxy [*] ((* ': Lbl n ns desc) xs)) :: * Source #

Methods

(.*.) :: to p q -> Proxy [*] ((* ': Lbl n ns desc) xs) -> HExtendR (to p q) (Proxy [*] ((* ': Lbl n ns desc) xs)) Source #

((~) (* -> * -> *) to (LabeledTo Symbol x), ToSym * (to p q) x) => HExtend (to p q) (Proxy [Symbol] ((:) Symbol x xs)) Source # 

Associated Types

type HExtendR (to p q) (Proxy [Symbol] ((Symbol ': x) xs)) :: * Source #

Methods

(.*.) :: to p q -> Proxy [Symbol] ((Symbol ': x) xs) -> HExtendR (to p q) (Proxy [Symbol] ((Symbol ': x) xs)) Source #

((~) (* -> * -> *) to (LabeledTo Symbol x), ToSym * (to p q) x) => HExtend (to p q) (Proxy [*] ([] *)) Source #

Together with the instance below, this allows writing

makeLabelable "x y z"
p = x .*. y .*. z .*. emptyProxy

Or with HListPP

p = `x .*. `y .*. `z .*. emptyProxy

instead of

p = Proxy :: Proxy ["x","y","z"]

Associated Types

type HExtendR (to p q) (Proxy [*] [*]) :: * Source #

Methods

(.*.) :: to p q -> Proxy [*] [*] -> HExtendR (to p q) (Proxy [*] [*]) Source #