Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
The HList library
(C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke
Type-indexed products. The public interface is described in CommonMain#TIP
Synopsis
- module Data.HList.TIPtuple
- class TransTIPM2 (b :: Bool) m arg op db where
- class Monad m => TransTIPM1 (b :: Bool) (n :: HNat) m op db where
- class Monad m => TransTIPM m op db where
- class TransTIP2 (b :: Bool) arg op db where
- class TransTIP1 (b :: Bool) (n :: HNat) op db where
- class TransTIP op db where
- type family Untag1 (x :: *) :: *
- type family UntagR (ta :: [*]) :: [*]
- type family TagR (a :: [*]) :: [*]
- type UntagTag xs = (TagR (UntagR xs) ~ xs, TagUntagFD (UntagR xs) xs)
- type TagUntag xs = TagUntagFD xs (TagR xs)
- class SameLength a ta => TagUntagFD a ta | a -> ta, ta -> a where
- class HAllTaggedEq (l :: [*])
- class (HAllTaggedEq l, HRLabelSet l) => HTypeIndexed (l :: [*])
- newtype TIP (l :: [*]) = TIP {}
- mkTIP :: HTypeIndexed l => HList l -> TIP l
- emptyTIP :: TIP '[]
- onRecord :: forall {l :: [Type]} {r :: [Type]}. (HAllTaggedEq l, HLabelSet (LabelsOf l), HAllTaggedLV l) => (Record r -> Record l) -> TIP r -> TIP l
- tipyUpdate :: forall {record} {v} {r :: [Type]}. (HUpdateAtLabel record v v r r, SameLength' r r) => v -> record r -> record r
- tipyProject :: forall {l :: [Type]} {ls :: [Type]} {r :: [Type]} {b :: [Type]} {proxy}. (HAllTaggedEq l, HLabelSet (LabelsOf l), HAllTaggedLV l, H2ProjectByLabels ls r l b) => proxy ls -> TIP r -> TIP l
- tipyLens' :: forall {a} {t :: [Type]} {f}. (HasField a (Record t) a, HUpdateAtLabel2 a a t t, HAllTaggedEq t, HLabelSet (LabelsOf t), HAllTaggedLV t, SameLength' t t, SameLabels t t, Functor f) => (a -> f a) -> TIP t -> f (TIP t)
- tipyLens :: forall {n :: HNat} {x} {xs :: [Type]} {l1 :: [Type]} {a} {xs :: [Type]} {b :: Bool} {a} {f}. (HSplitAt1 ('[] :: [Type]) n (Tagged x x ': xs) l1 (Tagged a a ': xs), HAppendList1 l1 (Tagged a a ': xs) (Tagged x x ': xs), SameLength' (HReplicateR n ()) l1, HLengthEq1 l1 n, HLengthEq2 l1 n, HEq (Label a) (Label x) b, HFind2 b (Label a) (LabelsOf xs) (Label x ': LabelsOf xs) n, HAllTaggedEq (HAppendListR l1 (Tagged a a ': xs)), HLabelSet (LabelsOf (HAppendListR l1 (Tagged a a ': xs))), HAllTaggedLV (HAppendListR l1 (Tagged a a ': xs)), HAppendList l1 (Tagged a a ': xs), Functor f) => (a -> f a) -> TIP (Tagged x x ': xs) -> f (TIP (HAppendListR l1 (Tagged a a ': xs)))
- tipyProject2 :: forall {ls :: [Type]} {r :: [Type]} {l :: [Type]} {l :: [Type]} {proxy}. (H2ProjectByLabels ls r l l, HAllTaggedEq l, HAllTaggedEq l, HLabelSet (LabelsOf l), HLabelSet (LabelsOf l), HAllTaggedLV l, HAllTaggedLV l) => proxy ls -> TIP r -> (TIP l, TIP l)
- tipHList :: forall {p} {f} {a :: [Type]} {ta :: [Type]} {a :: [Type]} {l :: [Type]}. (Profunctor p, Functor f, TagUntagFD a ta, TagUntagFD a l) => p (HList a) (f (HList a)) -> p (TIP ta) (f (TIP l))
- tipHList' :: forall {p} {f} {a :: [Type]} {l :: [Type]}. (Profunctor p, Functor f, TagUntagFD a l) => p (HList a) (f (HList a)) -> p (TIP l) (f (TIP l))
- tipRecord :: forall {p} {f} {r :: [Type]} {l :: [Type]}. (Profunctor p, Functor f) => p (Record r) (f (Record l)) -> p (TIP r) (f (TIP l))
- tipRecord' :: forall {p} {f} {l :: [Type]}. (Profunctor p, Functor f) => p (Record l) (f (Record l)) -> p (TIP l) (f (TIP l))
- hZipTIP :: forall {x :: [Type]} {y :: [Type]} {a :: [Type]} {l :: [Type]} {ta :: [Type]} {ta :: [Type]}. (HZipList x y a, TagUntagFD a l, TagUntagFD x ta, TagUntagFD y ta) => TIP ta -> TIP ta -> TIP l
- hUnzipTIP :: forall {a :: [Type]} {a :: [Type]} {l :: [Type]} {l :: [Type]} {l :: [Type]} {ta :: [Type]}. (HZipList a a l, HAllTaggedEq l, HAllTaggedEq l, HLabelSet (LabelsOf l), HLabelSet (LabelsOf l), HAllTaggedLV l, HAllTaggedLV l, TagUntagFD l ta, TagUntagFD a l, TagUntagFD a l) => TIP ta -> (TIP l, TIP l)
Documentation
module Data.HList.TIPtuple
class TransTIPM2 (b :: Bool) m arg op db where Source #
Instances
Fail (FieldNotFound op (TIP db)) => TransTIPM2 'False m arg op db Source # | |
(HOccurs arg (TIP db), TransTIPM m op db) => TransTIPM2 'True m arg op db Source # | |
class Monad m => TransTIPM1 (b :: Bool) (n :: HNat) m op db where Source #
Instances
(Fail (FieldNotFound op (TIP db)), Monad m) => TransTIPM1 'False 'HZero m op db Source # | |
(Monad m, m ~ m', HTPupdateAtLabel TIP op op db) => TransTIPM1 'True n m (m' op) db Source # | |
(Monad m, HMember (Tagged arg arg) db b, TransTIPM2 b m arg op db) => TransTIPM1 'False ('HSucc n) m (arg -> op) db Source # | |
class Monad m => TransTIPM m op db where Source #
In March 2010, Andrew Frank extended the problem for monadic operations.
This is the monadic version of TIPTransform.hs
in the present directory.
This is the TF implementation. When specifying the operation to perform over a TIP, we can leave it polymorphic over the monad. The type checker will instantiate the monad based on the context.
class TransTIP1 (b :: Bool) (n :: HNat) op db where Source #
class TransTIP op db where Source #
Transforming a TIP: applying to a TIP a (polyvariadic) function that takes arguments from a TIP and updates the TIP with the result.
In more detail: we have a typed-indexed collection TIP and we would like to apply a transformation function to it, whose argument types and the result type are all in the TIP. The function should locate its arguments based on their types, and update the TIP with the result. The function may have any number of arguments, including zero; the order of arguments should not matter.
The problem was posed by Andrew U. Frank on Haskell-Cafe, Sep 10, 2009. http://www.haskell.org/pipermail/haskell-cafe/2009-September/066217.html The problem is an interesting variation of the keyword argument problem.
Examples can be found in examples/TIPTransform.hs
and examples/TIPTransformM.hs
type UntagTag xs = (TagR (UntagR xs) ~ xs, TagUntagFD (UntagR xs) xs) Source #
Sometimes the type variables available have TagR
already applied
(ie the lists have elements like Tagged X X
). Then this abbreviation
is useful:
type TagUntag xs = TagUntagFD xs (TagR xs) Source #
class SameLength a ta => TagUntagFD a ta | a -> ta, ta -> a where Source #
TagR
can also be used to avoid redundancy when defining types for TIC and TIP.
type XShort = TagR [A,B,C,D]
type XLong = [Tagged A A, Tagged B B, Tagged C C, Tagged D D]
an equivalent FD version, which is slightly better with respect to simplifying types containing type variables (in ghc-7.8 and 7.6): http://stackoverflow.com/questions/24110410/
With ghc-7.10 (http://ghc.haskell.org/trac/ghc/ticket/10009) the FD version is superior to the TF version:
class (UntagR (TagR a) ~ a) => TagUntag a where type TagR a :: [*] hTagSelf :: HList a -> HList (TagR a) hUntagSelf :: HList (TagR a) -> HList a instance TagUntag '[] where type TagR '[] = '[] hTagSelf _ = HNil hUntagSelf _ = HNil instance TagUntag xs => TagUntag (x ': xs) where type TagR (x ': xs) = Tagged x x ': TagR xs hTagSelf (HCons x xs) = Tagged xHCons
hTagSelf xs hUntagSelf (HCons (Tagged x) xs) = xHCons
hUntagSelf xs type family UntagR (xs :: [*]) :: [*] type instance UntagR '[] = '[] type instance UntagR (x ': xs) = Untag1 x ': UntagR xs
Length information should flow backwards
>>>
let len2 x = x `asTypeOf` (undefined :: HList '[a,b])
>>>
let f = len2 $ hTagSelf (hReplicate Proxy ())
>>>
:t f
f :: HList '[Tagged () (), Tagged () ()]
Instances
TagUntagFD ('[] :: [Type]) ('[] :: [Type]) Source # | |
(TagUntagFD xs ys, txx ~ Tagged x x) => TagUntagFD (x ': xs) (txx ': ys) Source # | |
class HAllTaggedEq (l :: [*]) Source #
Instances
HAllTaggedEq ('[] :: [Type]) Source # | |
Defined in Data.HList.TIP | |
(HAllTaggedEq l, tee ~ Tagged e e') => HAllTaggedEq (tee ': l) Source # | |
Defined in Data.HList.TIP |
class (HAllTaggedEq l, HRLabelSet l) => HTypeIndexed (l :: [*]) Source #
this constraint ensures that a TIP created by mkTIP
has no
duplicates
Instances
(HAllTaggedEq l, HRLabelSet l) => HTypeIndexed l Source # | |
Defined in Data.HList.TIP |
newtype TIP (l :: [*]) Source #
TIPs are like Record
, except element "i" of the list "l"
has type Tagged e_i e_i
Instances
TypeIndexed Record TIP Source # | |
Defined in Data.HList.TIC | |
(HZipList xL yL xyL, lty ~ (HList xyL -> (HList xL, HList yL)), Coercible lty (TIP xy -> (TIP x, TIP y)), UntagR x ~ xL, TagR xL ~ x, UntagR y ~ yL, TagR yL ~ y, UntagR xy ~ xyL, TagR xyL ~ xy, SameLengths '[x, y, xy], UntagTag x, UntagTag y, UntagTag xy) => HUnzip TIP x y xy Source # | |
(HUnzip TIP x y xy, HZipList xL yL xyL, lty ~ (HList xL -> HList yL -> HList xyL), Coercible lty (TIP x -> TIP y -> TIP xy), UntagR x ~ xL, UntagR y ~ yL, UntagR xy ~ xyL, UntagTag x, UntagTag y, UntagTag xy) => HZip TIP x y xy Source # | |
(HDeleteAtLabel Record e v v', HTypeIndexed v') => HDeleteAtLabel TIP (e :: k) v v' Source # | |
Defined in Data.HList.TIP | |
(HUpdateAtLabel Record e' e r r', HTypeIndexed r', e ~ e') => HUpdateAtLabel TIP (e' :: Type) e r r' Source # | |
Defined in Data.HList.TIP | |
LabelableTIPCxt x s t a b => Labelable (x :: k) TIP s t a b Source # | make a
|
Defined in Data.HList.Labelable type LabelableTy TIP :: LabeledOpticType Source # | |
(e ~ e', HasField e (Record l) e') => HasField (e :: Type) (TIP l) e' Source # | |
Defined in Data.HList.TIP hLookupByLabel :: Label e -> TIP l -> e' Source # | |
SubType (TIP l :: Type) (TIP ('[] :: [Type])) Source # | Subtyping for TIPs |
Defined in Data.HList.TIP | |
(HOccurs e (TIP l1), SubType (TIP l1) (TIP l2)) => SubType (TIP l1 :: Type) (TIP (e ': l2) :: Type) Source # | |
Defined in Data.HList.TIP | |
(HRLabelSet (Tagged e e ': l), HTypeIndexed l) => HExtend e (TIP l) Source # | |
tee ~ Tagged e e => HOccurs e (TIP '[tee]) Source # | One occurrence and nothing is left This variation provides an extra feature for singleton lists. That is, the result type is unified with the element in the list. Hence the explicit provision of a result type can be omitted. |
Defined in Data.HList.TIP | |
HasField e (Record (x ': (y ': l))) e => HOccurs e (TIP (x ': (y ': l))) Source # | |
Defined in Data.HList.TIP | |
(TypeablePolyK xs, Typeable (HList xs), Data (HList xs)) => Data (TIP xs) Source # | |
Defined in Data.HList.Data gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> TIP xs -> c (TIP xs) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (TIP xs) # toConstr :: TIP xs -> Constr # dataTypeOf :: TIP xs -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (TIP xs)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (TIP xs)) # gmapT :: (forall b. Data b => b -> b) -> TIP xs -> TIP xs # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> TIP xs -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> TIP xs -> r # gmapQ :: (forall d. Data d => d -> u) -> TIP xs -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> TIP xs -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> TIP xs -> m (TIP xs) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> TIP xs -> m (TIP xs) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> TIP xs -> m (TIP xs) # | |
Monoid (HList a) => Monoid (TIP a) Source # | |
Semigroup (HList a) => Semigroup (TIP a) Source # | |
Bounded (HList r) => Bounded (TIP r) Source # | |
Ix (HList r) => Ix (TIP r) Source # | |
HMapOut (HComp HShow HUntag) l String => Show (TIP l) Source # | |
Eq (HList a) => Eq (TIP a) Source # | |
Ord (HList r) => Ord (TIP r) Source # | |
(HAppend (HList l) (HList l'), HTypeIndexed (HAppendListR l l')) => HAppend (TIP l) (TIP l') Source # | |
type LabelableTy TIP Source # | |
Defined in Data.HList.Labelable | |
type HExtendR e (TIP l) Source # | |
Defined in Data.HList.TIP | |
type HAppendR (TIP l :: Type) (TIP l' :: Type) Source # | |
Defined in Data.HList.TIP |
onRecord :: forall {l :: [Type]} {r :: [Type]}. (HAllTaggedEq l, HLabelSet (LabelsOf l), HAllTaggedLV l) => (Record r -> Record l) -> TIP r -> TIP l Source #
tipyUpdate :: forall {record} {v} {r :: [Type]}. (HUpdateAtLabel record v v r r, SameLength' r r) => v -> record r -> record r Source #
tipyProject :: forall {l :: [Type]} {ls :: [Type]} {r :: [Type]} {b :: [Type]} {proxy}. (HAllTaggedEq l, HLabelSet (LabelsOf l), HAllTaggedLV l, H2ProjectByLabels ls r l b) => proxy ls -> TIP r -> TIP l Source #
Use Labels
to specify the first argument
tipyLens' :: forall {a} {t :: [Type]} {f}. (HasField a (Record t) a, HUpdateAtLabel2 a a t t, HAllTaggedEq t, HLabelSet (LabelsOf t), HAllTaggedLV t, SameLength' t t, SameLabels t t, Functor f) => (a -> f a) -> TIP t -> f (TIP t) Source #
provides a Lens' (TIP s) a
. hLens'
:: Label a -> Lens' (TIP s) a
is another option.
tipyLens :: forall {n :: HNat} {x} {xs :: [Type]} {l1 :: [Type]} {a} {xs :: [Type]} {b :: Bool} {a} {f}. (HSplitAt1 ('[] :: [Type]) n (Tagged x x ': xs) l1 (Tagged a a ': xs), HAppendList1 l1 (Tagged a a ': xs) (Tagged x x ': xs), SameLength' (HReplicateR n ()) l1, HLengthEq1 l1 n, HLengthEq2 l1 n, HEq (Label a) (Label x) b, HFind2 b (Label a) (LabelsOf xs) (Label x ': LabelsOf xs) n, HAllTaggedEq (HAppendListR l1 (Tagged a a ': xs)), HLabelSet (LabelsOf (HAppendListR l1 (Tagged a a ': xs))), HAllTaggedLV (HAppendListR l1 (Tagged a a ': xs)), HAppendList l1 (Tagged a a ': xs), Functor f) => (a -> f a) -> TIP (Tagged x x ': xs) -> f (TIP (HAppendListR l1 (Tagged a a ': xs))) Source #
provides a Lens (TIP s) (TIP t) a b
When using set
(also known as .~
), tipyLens'
can address the
ambiguity as to which field "a" should actually be updated.
tipyProject2 :: forall {ls :: [Type]} {r :: [Type]} {l :: [Type]} {l :: [Type]} {proxy}. (H2ProjectByLabels ls r l l, HAllTaggedEq l, HAllTaggedEq l, HLabelSet (LabelsOf l), HLabelSet (LabelsOf l), HAllTaggedLV l, HAllTaggedLV l) => proxy ls -> TIP r -> (TIP l, TIP l) Source #
The same as tipyProject
, except also return the
types not requested in the proxy
argument
tipHList :: forall {p} {f} {a :: [Type]} {ta :: [Type]} {a :: [Type]} {l :: [Type]}. (Profunctor p, Functor f, TagUntagFD a ta, TagUntagFD a l) => p (HList a) (f (HList a)) -> p (TIP ta) (f (TIP l)) Source #
Iso (TIP (TagR a)) (TIP (TagR b)) (HList a) (HList b)
tipHList' :: forall {p} {f} {a :: [Type]} {l :: [Type]}. (Profunctor p, Functor f, TagUntagFD a l) => p (HList a) (f (HList a)) -> p (TIP l) (f (TIP l)) Source #
Iso' (TIP (TagR s)) (HList a)
tipRecord :: forall {p} {f} {r :: [Type]} {l :: [Type]}. (Profunctor p, Functor f) => p (Record r) (f (Record l)) -> p (TIP r) (f (TIP l)) Source #
Iso (TIP s) (TIP t) (Record s) (Record t)
typeIndexed
may be more appropriate
tipRecord' :: forall {p} {f} {l :: [Type]}. (Profunctor p, Functor f) => p (Record l) (f (Record l)) -> p (TIP l) (f (TIP l)) Source #
Iso' (TIP (TagR s)) (Record a)
hZipTIP :: forall {x :: [Type]} {y :: [Type]} {a :: [Type]} {l :: [Type]} {ta :: [Type]} {ta :: [Type]}. (HZipList x y a, TagUntagFD a l, TagUntagFD x ta, TagUntagFD y ta) => TIP ta -> TIP ta -> TIP l Source #
specialization of hZip
hUnzipTIP :: forall {a :: [Type]} {a :: [Type]} {l :: [Type]} {l :: [Type]} {l :: [Type]} {ta :: [Type]}. (HZipList a a l, HAllTaggedEq l, HAllTaggedEq l, HLabelSet (LabelsOf l), HLabelSet (LabelsOf l), HAllTaggedLV l, HAllTaggedLV l, TagUntagFD l ta, TagUntagFD a l, TagUntagFD a l) => TIP ta -> (TIP l, TIP l) Source #
specialization of hUnzip