Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
- Heterogeneous type sequences
- Basic list functions
- Reversing HLists
- A nicer notation for lists
- folds
- unfolds
- concat
- traversing HLists
- Ensure a list to contain HNats only
- Membership tests
- Staged equality for lists
- Find an element in a set based on HEq
- Intersection based on HTMember
- Convert between heterogeneous lists and homogeneous ones
- With
HMaybe
- Annotated lists
- Splitting by HTrue and HFalse
- Splitting by Length
- Conversion to and from tuples
- partition
- groupBy
- span
- zip
- Monoid instance
The HList library
(C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke
Basic declarations for typeful heterogeneous lists.
Synopsis
- data family HList (l :: [*])
- class HProxiesFD (xs :: [*]) pxs | pxs -> xs, xs -> pxs where
- type HProxies xs = HProxiesFD xs (AddProxy xs)
- type family AddProxy (xs :: k) :: k
- type family DropProxy (xs :: k) :: k
- data ReadElement = ReadElement
- hHead :: HList (e ': l) -> e
- hTail :: HList (e ': l) -> HList l
- hLast :: forall {l1 :: [Type]} {e} {l :: [Type]}. HRevApp l1 ('[] :: [Type]) (e ': l) => HList l1 -> e
- class HInit xs where
- type family HLength (x :: [k]) :: HNat
- hLength :: HLengthEq l n => HList l -> Proxy n
- type family HAppendListR (l1 :: [k]) (l2 :: [k]) :: [k]
- class HAppendList l1 l2 where
- hAppendList :: HList l1 -> HList l2 -> HList (HAppendListR l1 l2)
- append' :: [a] -> [a] -> [a]
- hAppend' :: HFoldr FHCons v l r => HList l -> v -> r
- data FHCons = FHCons
- type family HRevAppR (l1 :: [k]) (l2 :: [k]) :: [k]
- class HRevApp l1 l2 l3 | l1 l2 -> l3 where
- class HReverse xs sx | xs -> sx, sx -> xs where
- hReverse_ :: forall {l1 :: [Type]} {l3 :: [Type]}. HRevApp l1 ('[] :: [Type]) l3 => HList l1 -> HList l3
- hEnd :: HList l -> HList l
- hBuild :: HBuild' '[] r => r
- class HBuild' l r where
- class HFoldr f v (l :: [*]) r where
- class HScanr f z ls rs where
- class HFoldr1 f (l :: [*]) r where
- class HFoldl f (z :: *) xs (r :: *) where
- hUnfold :: forall {f} {a} {z :: [Type]}. (HUnfoldFD f (ApplyR f a) z, Apply f a) => f -> a -> HList z
- type HUnfold p s = HUnfoldR p (ApplyR p s)
- type family HUnfoldR p res :: [*]
- type HUnfold' p res = HUnfoldFD p (ApplyR p res) (HUnfold p res)
- class HUnfoldFD p res z | p res -> z where
- class HLengthEq es n => HReplicateFD (n :: HNat) e es | n e -> es, es -> n where
- hReplicate :: Proxy n -> e -> HList es
- type HReplicate n e = HReplicateFD n e (HReplicateR n e)
- type family HReplicateR (n :: HNat) (e :: k) :: [k]
- class HLengthEq r n => HReplicateF (n :: HNat) f z r | r -> n where
- hReplicateF :: HLengthEq r n => Proxy n -> f -> z -> HList r
- class HLengthEq r n => HIterate n f z r where
- type HConcat xs = HConcatFD xs (HConcatR xs)
- hConcat :: HConcat xs => HList xs -> HList (HConcatR xs)
- type family HConcatR (a :: [*]) :: [*]
- type family UnHList a :: [*]
- class HConcatFD xxs xs | xxs -> xs where
- class HAppendFD a b ab | a b -> ab where
- newtype HMap f = HMap f
- hMap :: forall {a :: [Type]} {b :: [Type]} {r} {f}. (SameLength' a b, SameLength' b a, HMapAux r f a b) => f -> r a -> r b
- hMapL :: forall {a :: [Type]} {b :: [Type]} {f}. (SameLength' a b, SameLength' b a, HMapAux HList f a b) => f -> HList a -> HList b
- newtype HMapL f = HMapL f
- class (SameLength a b, HMapAux r f a b) => HMapCxt r f a b
- class HMapAux (r :: [*] -> *) f (x :: [*]) (y :: [*]) where
- hMapAux :: SameLength x y => f -> r x -> r y
- newtype MapCar f = MapCar f
- hMapMapCar :: HFoldr (MapCar f) (HList '[]) l l' => f -> HList l -> l'
- hComposeList :: HFoldr Comp (a -> a) l (t -> a) => HList l -> t -> a
- class (Applicative m, SameLength a b) => HSequence m a b | a -> b, m b -> a where
- hSequence2 :: forall {f} {l :: [Type]} {a}. (Applicative f, HFoldr (LiftA2 FHCons) (f (HList ('[] :: [Type]))) l (f a)) => HList l -> f a
- newtype Mapcar f = Mapcar f
- type HMapOut f l e = HFoldr (Mapcar f) [e] l [e]
- hMapOut :: forall f e l. HMapOut f l e => f -> HList l -> [e]
- hMapM :: (Monad m, HMapOut f l (m e)) => f -> HList l -> [m e]
- hMapM_ :: (Monad m, HMapOut f l (m ())) => f -> HList l -> m ()
- type family HNats (l :: [*]) :: [HNat]
- hNats :: HList l -> Proxy (HNats l)
- class HMember (e1 :: k) (l :: [k]) (b :: Bool) | e1 l -> b
- class HMember' (b0 :: Bool) (e1 :: k) (l :: [k]) (b :: Bool) | b0 e1 l -> b
- type family HMemberP pred e1 (l :: [*]) :: Bool
- type family HMemberP' pred e1 (l :: [*]) pb :: Bool
- hMember :: HMember e l b => Proxy e -> Proxy l -> Proxy b
- class HMemberM (e1 :: k) (l :: [k]) (r :: Maybe [k]) | e1 l -> r
- class HMemberM1 (b :: Bool) (e1 :: k) (l :: [k]) (r :: Maybe [k]) | b e1 l -> r
- class HMemberM2 (b :: Maybe [k]) (e1 :: k) (l :: [k]) (r :: Maybe [k]) | b e1 l -> r
- class HFind1 e l l n => HFind (e :: k) (l :: [k]) (n :: HNat) | e l -> n
- class HFind1 (e :: k) (l :: [k]) (l0 :: [k]) (n :: HNat) | e l -> n
- class HFind2 (b :: Bool) (e :: k) (l :: [k]) (l0 :: [k]) (n :: HNat) | b e l -> n
- class HTMember e (l :: [*]) (b :: Bool) | e l -> b
- hTMember :: HTMember e l b => e -> HList l -> Proxy b
- class HTIntersect l1 l2 l3 | l1 l2 -> l3 where
- hTIntersect :: HList l1 -> HList l2 -> HList l3
- class HTIntersectBool (b :: Bool) h t l1 l2 | b h t l1 -> l2 where
- hTIntersectBool :: Proxy b -> h -> HList t -> HList l1 -> HList l2
- class HList2List l e | l -> e where
- hList2List :: HList l -> [e]
- list2HListSuffix :: [e] -> Maybe (HList l, [e])
- list2HList :: HList2List l e => [e] -> Maybe (HList l)
- listAsHList :: forall {p} {f} {l :: [Type]} {e} {l :: [Type]} {e}. (Choice p, Applicative f, HList2List l e, HList2List l e) => p (HList l) (f (HList l)) -> p [e] (f [e])
- listAsHList' :: forall {p} {f} {l :: [Type]} {e}. (Choice p, Applicative f, HList2List l e) => p (HList l) (f (HList l)) -> p [e] (f [e])
- class FromHJustR (ToHJustR l) ~ l => ToHJust l where
- toHJust2 :: (HMapCxt r (HJust ()) a b, ToHJust a, b ~ ToHJustR a) => r a -> r b
- class FromHJustR (ToHJustR l) ~ l => FromHJust l where
- type FromHJustR l :: [*]
- fromHJust :: HList l -> HList (FromHJustR l)
- fromHJust2 :: HMapCxt r HFromJust a b => r a -> r b
- data HFromJust = HFromJust
- data HAddTag t = HAddTag t
- data HRmTag = HRmTag
- hAddTag :: forall {a :: [Type]} {b :: [Type]} {r} {t}. (SameLength' a b, SameLength' b a, HMapAux r (HAddTag t) a b) => t -> r a -> r b
- hRmTag :: forall {a :: [Type]} {b :: [Type]} {r}. (SameLength' a b, SameLength' b a, HMapAux r HRmTag a b) => r a -> r b
- hFlag :: forall {a :: [Type]} {b :: [Type]} {r}. (SameLength' a b, SameLength' b a, HMapAux r (HAddTag (Proxy 'True)) a b) => r a -> r b
- class HSplit l where
- class (HLengthEq xs n, HAppendList1 xs ys xsys) => HSplitAt (n :: HNat) xsys xs ys | n xsys -> xs ys, xs ys -> xsys, xs -> n where
- class HSplitAt1 accum (n :: HNat) xsys xs ys | accum n xsys -> xs ys where
- class (SameLength' (HReplicateR n ()) xs, HLengthEq1 xs n, HLengthEq2 xs n) => HLengthEq (xs :: [*]) (n :: HNat) | xs -> n
- class HLengthEq1 (xs :: [*]) n
- class HLengthEq2 (xs :: [*]) n | xs -> n
- class HLengthGe (xs :: [*]) (n :: HNat)
- class HStripPrefix xs xsys ys => HAppendList1 (xs :: [k]) (ys :: [k]) (xsys :: [k]) | xs ys -> xsys, xs xsys -> ys
- class HStripPrefix xs xsys ys | xs xsys -> ys
- class HTake (n :: HNat) xs ys | n xs -> ys where
- class HDrop (n :: HNat) xs ys | n xs -> ys where
- class HTuple v t | v -> t, t -> v where
- hToTuple :: HList v -> t
- hFromTuple :: t -> HList v
- hTuple :: forall {p} {f} {v :: [Type]} {a} {v :: [Type]} {b}. (Profunctor p, Functor f, HTuple v a, HTuple v b) => p a (f b) -> p (HList v) (f (HList v))
- hTuple' :: forall {p} {f} {v :: [Type]} {a}. (Profunctor p, Functor f, HTuple v a) => p a (f a) -> p (HList v) (f (HList v))
- class HTails a b | a -> b, b -> a where
- class HInits a b | a -> b, b -> a where
- class HInits1 a b | a -> b, b -> a where
- data FHCons2 x = FHCons2 x
- type family HMapCons (x :: *) (xxs :: [*]) :: [*]
- type family HMapTail (xxs :: [*]) :: [*]
- class HPartitionEq f x1 xs xi xo | f x1 xs -> xi xo where
- class HPartitionEq1 (b :: Bool) f x1 x xs xi xo | b f x1 x xs -> xi xo where
- class HGroupBy (f :: t) (as :: [*]) (gs :: [*]) | f as -> gs, gs -> as where
- class HSpanEqBy (f :: t) (x :: *) (y :: [*]) (fst :: [*]) (snd :: [*]) | f x y -> fst snd, fst snd -> y where
- class HSpanEqBy1 (f :: t) (x :: *) (y :: [*]) (i :: [*]) (o :: [*]) | f x y -> i o where
- hSpanEqBy1 :: Proxy f -> x -> HList y -> (HList i, HList o)
- class HSpanEqBy2 (b :: Bool) (f :: t) (x :: *) (y :: *) (ys :: [*]) (i :: [*]) (o :: [*]) | b f x y ys -> i o where
- class HZipList x y l | x y -> l, l -> x y where
- data ConstMempty = ConstMempty
- data UncurryMappend = UncurryMappend
- data UncurrySappend = UncurrySappend
Heterogeneous type sequences
There are three sensible ways to define HLists:
data HList (l::[*]) where HNil :: HList '[] HCons :: e -> HList l -> HList (e ': l)
This ensures that sequences can only be formed with Nil
and Cons. The argument to HList is a promoted lists (kind [*]
),
which has a more attractive syntax.
Earlier versions of HList used an algebraic data type:
data HCons a b = HCons a b data HNil = HNil
Disadvantages:
- values with types like
HCons Int Double
to be created, which are nonsense to the functions in HList - some recursive functions do not need a class with the GADT. For example:
hInit :: HListGADT (x ': xs) -> HListGADT (HInit (x ': xs)) hInit (HCons x xs@(HCons _ _)) = HCons x (hInit xs) hInit (HCons _ HNil) = HNil type family HInit (xs :: [k]) :: [k]
but without the GADT, hInit
is written as in a class,
which complicates inferred types
Advantages
- lazy pattern matches are allowed, so lazy pattern matching
on a value
undefined :: HList [a,b,c]
can create the spine of the list.hProxies
avoids the use ofundefined
, but a slightly more complicated class context has to be written or inferred. - type inference is better if you want to directly pattern match see stackoverflow post here
- better pattern exhaustiveness checking (as of ghc-7.8)
- standalone deriving works
- Data.Coerce.coerce works because the parameters have role representational, not nominal as they are for the GADT and data family. Probably the GADT/type family actually do have a representational role: http://stackoverflow.com/questions/24222552/does-this-gadt-actually-have-type-role-representational
The data family version (currently used) gives the same type constructor
HList :: [*] -> *
as the GADT, while pattern matching behaves
like the algebraic data type. Furthermore, nonsense values like
HCons 1 2 :: HCons Int Int
cannot be written with the data family.
A variation on the data family version is
data instance HList '[] = HNil newtype instance HList (x ': xs) = HCons1 (x, HList xs) pattern HCons x xs = HCons1 (x, xs)
This allows HList to have a nominal role, but on the other hand the PatternSynonym is not supported with ghc-7.6 and exhaustiveness checking is not as good (warnings for _ being unmatched)
data family HList (l :: [*]) infixr 2 Source #
Instances
(SameLengths '[x, y, xy], HZipList x y xy) => HUnzip HList x y xy Source # | |
(SameLengths '[x, y, xy], HZipList x y xy) => HZip HList x y xy Source # | |
(HDeleteAtHNat n l, HType2HNat e l n, l' ~ HDeleteAtHNatR n l) => HDeleteAtLabel HList (e :: Type) l l' Source # | should this instead delete the first element of that type? |
Defined in Data.HList.HTypeIndexed | |
HMapAux HList f ('[] :: [Type]) ('[] :: [Type]) Source # | |
(HEq e1 e b, HDeleteManyCase b e1 e l l1) => HDeleteMany (e1 :: Type) (HList (e ': l)) (HList l1) Source # | |
Defined in Data.HList.HTypeIndexed | |
HDeleteMany (e :: k) (HList ('[] :: [Type])) (HList ('[] :: [Type])) Source # | |
Defined in Data.HList.HTypeIndexed | |
(HSpanEqBy f a as fst snd, HGroupBy f snd gs) => HGroupBy (f :: t) (a ': as) (HList (a ': fst) ': gs) Source # | |
(ApplyAB f e e', HMapAux HList f l l', SameLength l l') => HMapAux HList f (e ': l) (e' ': l') Source # | |
HReverse l l' => HBuild' l (HList l') Source # | |
HExtend e (HList l) Source # | |
(HOccurrence e (x ': y) l', HOccurs' e l' (x ': y)) => HOccurs e (HList (x ': y)) Source # | |
Defined in Data.HList.HOccurs | |
(HOccurs e l, HProject l (HList l')) => HProject l (HList (e ': l')) Source # | |
Defined in Data.HList.HOccurs | |
HInits1 a b => HInits a (HList ('[] :: [Type]) ': b) Source # | |
(TypeRepsList (HList xs), Typeable x) => TypeRepsList (HList (x ': xs)) Source # | |
Defined in Data.HList.Data typeRepsList :: HList (x ': xs) -> [TypeRep] Source # | |
TypeRepsList (HList ('[] :: [Type])) Source # | |
Defined in Data.HList.Data typeRepsList :: HList '[] -> [TypeRep] Source # | |
(Data x, Data (HList xs), TypeablePolyK (x ': xs), Typeable (HList (x ': xs))) => Data (HList (x ': xs)) Source # | |
Defined in Data.HList.Data gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> HList (x ': xs) -> c (HList (x ': xs)) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (HList (x ': xs)) # toConstr :: HList (x ': xs) -> Constr # dataTypeOf :: HList (x ': xs) -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (HList (x ': xs))) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (HList (x ': xs))) # gmapT :: (forall b. Data b => b -> b) -> HList (x ': xs) -> HList (x ': xs) # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> HList (x ': xs) -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> HList (x ': xs) -> r # gmapQ :: (forall d. Data d => d -> u) -> HList (x ': xs) -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> HList (x ': xs) -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> HList (x ': xs) -> m (HList (x ': xs)) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> HList (x ': xs) -> m (HList (x ': xs)) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> HList (x ': xs) -> m (HList (x ': xs)) # | |
Typeable (HList ('[] :: [Type])) => Data (HList ('[] :: [Type])) Source # | |
Defined in Data.HList.Data gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> HList '[] -> c (HList '[]) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (HList '[]) # toConstr :: HList '[] -> Constr # dataTypeOf :: HList '[] -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (HList '[])) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (HList '[])) # gmapT :: (forall b. Data b => b -> b) -> HList '[] -> HList '[] # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> HList '[] -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> HList '[] -> r # gmapQ :: (forall d. Data d => d -> u) -> HList '[] -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> HList '[] -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> HList '[] -> m (HList '[]) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> HList '[] -> m (HList '[]) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> HList '[] -> m (HList '[]) # | |
(HProxies a, HMapCxt HList ConstMempty (AddProxy a) a, HZip HList a a aa, HMapCxt HList UncurryMappend aa a) => Monoid (HList a) Source # | Analogous to the Monoid instance for tuples
|
(HZip HList a a aa, HMapCxt HList UncurryMappend aa a) => Semigroup (HList a) Source # | |
(Bounded x, Bounded (HList xs)) => Bounded (HList (x ': xs)) Source # | |
Bounded (HList ('[] :: [Type])) Source # | |
(Ix x, Ix (HList xs)) => Ix (HList (x ': xs)) Source # | |
Defined in Data.HList.HList range :: (HList (x ': xs), HList (x ': xs)) -> [HList (x ': xs)] # index :: (HList (x ': xs), HList (x ': xs)) -> HList (x ': xs) -> Int # unsafeIndex :: (HList (x ': xs), HList (x ': xs)) -> HList (x ': xs) -> Int # inRange :: (HList (x ': xs), HList (x ': xs)) -> HList (x ': xs) -> Bool # rangeSize :: (HList (x ': xs), HList (x ': xs)) -> Int # unsafeRangeSize :: (HList (x ': xs), HList (x ': xs)) -> Int # | |
Ix (HList ('[] :: [Type])) Source # | |
Defined in Data.HList.HList range :: (HList '[], HList '[]) -> [HList '[]] # index :: (HList '[], HList '[]) -> HList '[] -> Int # unsafeIndex :: (HList '[], HList '[]) -> HList '[] -> Int # inRange :: (HList '[], HList '[]) -> HList '[] -> Bool # rangeSize :: (HList '[], HList '[]) -> Int # unsafeRangeSize :: (HList '[], HList '[]) -> Int # | |
(HProxies l, Read e, HSequence ReadP (ReadP e ': readP_l) (e ': l), HMapCxt HList ReadElement (AddProxy l) readP_l) => Read (HList (e ': l)) Source # | |
Read (HList ('[] :: [Type])) Source # | |
(Show e, Show (HList l)) => Show (HList (e ': l)) Source # | |
Show (HList ('[] :: [Type])) Source # | |
(Eq x, Eq (HList xs)) => Eq (HList (x ': xs)) Source # | |
Eq (HList ('[] :: [Type])) Source # | |
(Ord x, Ord (HList xs)) => Ord (HList (x ': xs)) Source # | |
Defined in Data.HList.HList compare :: HList (x ': xs) -> HList (x ': xs) -> Ordering # (<) :: HList (x ': xs) -> HList (x ': xs) -> Bool # (<=) :: HList (x ': xs) -> HList (x ': xs) -> Bool # (>) :: HList (x ': xs) -> HList (x ': xs) -> Bool # (>=) :: HList (x ': xs) -> HList (x ': xs) -> Bool # max :: HList (x ': xs) -> HList (x ': xs) -> HList (x ': xs) # min :: HList (x ': xs) -> HList (x ': xs) -> HList (x ': xs) # | |
Ord (HList ('[] :: [Type])) Source # | |
Defined in Data.HList.HList | |
HAppendList l1 l2 => HAppend (HList l1) (HList l2) Source # | |
HProject (HList l) (HList ('[] :: [Type])) Source # | |
ApplyAB f e e' => ApplyAB (MapCar f) (e, HList l) (HList (e' ': l)) Source # | |
HInits1 ('[] :: [Type]) '[HList ('[] :: [Type])] Source # | |
HTails ('[] :: [Type]) '[HList ('[] :: [Type])] Source # | |
(ch ~ Proxy (HBoolEQ sel (KMember n ns)), Apply (ch, FHUProj sel ns) (HList (e ': l), Proxy n)) => Apply (FHUProj sel ns) (HList (e ': l), Proxy n) Source # | |
Apply (FHUProj sel ns) (HList ('[] :: [Type]), n) Source # | |
Apply (FHUProj sel ns) (HList l, Proxy ('HSucc n)) => Apply (Proxy 'False, FHUProj sel ns) (HList (e ': l), Proxy n) Source # | |
Apply (Proxy 'True, FHUProj sel ns) (HList (e ': l), Proxy n) Source # | |
(HConcatFD as bs, HAppendFD a bs cs) => HConcatFD (HList a ': as) cs Source # | |
(HInits1 xs ys, HMapCxt HList (FHCons2 x) ys ys', HMapCons x ys ~ ys', HMapTail ys' ~ ys) => HInits1 (x ': xs) (HList '[x] ': ys') Source # | |
HTails xs ys => HTails (x ': xs) (HList (x ': xs) ': ys) Source # | |
HMapUnboxF xs us => HMapUnboxF (HList x ': xs) (RecordU x ': us) Source # | |
Defined in Data.HList.RecordU | |
(HList (x ': y) ~ z, HZip3 xs ys zs) => HZip3 (x ': xs) (HList y ': ys) (z ': zs) Source # | |
type HExtendR e (HList l) Source # | |
Defined in Data.HList.HList | |
type HAppendR (HList l1 :: Type) (HList l2 :: Type) Source # | |
Defined in Data.HList.HList | |
type HMapCons x (HList a ': b) Source # | |
Defined in Data.HList.HList | |
data HList ('[] :: [Type]) Source # | |
Defined in Data.HList.HList | |
type UnHList (HList a) Source # | |
Defined in Data.HList.HList | |
type ApplyR (FHUProj sel ns) (HList (e ': l), Proxy n) Source # | |
type ApplyR (FHUProj sel ns) (HList ('[] :: [Type]), n) Source # | |
type ApplyR (Proxy 'False, FHUProj sel ns) (HList (e ': l), Proxy n) Source # | |
type ApplyR (Proxy 'True, FHUProj sel ns) (HList (e ': l), Proxy n) Source # | |
data HList (x ': xs) Source # | |
Defined in Data.HList.HList | |
type HMapTail (HList (a ': as) ': bs) Source # | |
Defined in Data.HList.HList |
class HProxiesFD (xs :: [*]) pxs | pxs -> xs, xs -> pxs where Source #
creates a HList of Proxies
Instances
HProxiesFD ('[] :: [Type]) ('[] :: [Type]) Source # | |
Defined in Data.HList.HList | |
HProxiesFD xs pxs => HProxiesFD (x ': xs) (Proxy x ': pxs) Source # | |
type HProxies xs = HProxiesFD xs (AddProxy xs) Source #
type family AddProxy (xs :: k) :: k Source #
Add Proxy
to a type
>>>
let x = undefined :: HList (AddProxy [Char,Int])
>>>
:t x
x :: HList '[Proxy Char, Proxy Int]
Instances
type AddProxy (x :: Type) Source # | |
Defined in Data.HList.HList | |
type AddProxy ('[] :: [k]) Source # | |
Defined in Data.HList.HList type AddProxy ('[] :: [k]) = '[] :: [k] | |
type AddProxy (x ': xs :: [a]) Source # | |
Defined in Data.HList.HList |
type family DropProxy (xs :: k) :: k Source #
inverse of AddProxy
Instances
type DropProxy (Proxy x :: Type) Source # | |
Defined in Data.HList.HList | |
type DropProxy ('[] :: [k]) Source # | |
Defined in Data.HList.HList type DropProxy ('[] :: [k]) = '[] :: [k] | |
type DropProxy (x ': xs :: [a]) Source # | |
Defined in Data.HList.HList |
data ReadElement Source #
Instances
(y ~ ReadP x, Read x) => ApplyAB ReadElement (Proxy x) y Source # | |
Defined in Data.HList.HList applyAB :: ReadElement -> Proxy x -> y Source # |
Basic list functions
hLast :: forall {l1 :: [Type]} {e} {l :: [Type]}. HRevApp l1 ('[] :: [Type]) (e ': l) => HList l1 -> e Source #
Append
type family HAppendListR (l1 :: [k]) (l2 :: [k]) :: [k] Source #
Instances
type HAppendListR ('[] :: [k]) (l :: [k]) Source # | |
Defined in Data.HList.HList type HAppendListR ('[] :: [k]) (l :: [k]) = l | |
type HAppendListR (e ': l :: [k]) (l' :: [k]) Source # | |
Defined in Data.HList.HList |
class HAppendList l1 l2 where Source #
hAppendList :: HList l1 -> HList l2 -> HList (HAppendListR l1 l2) Source #
the same as hAppend
Instances
HAppendList ('[] :: [Type]) l2 Source # | |
Defined in Data.HList.HList hAppendList :: HList '[] -> HList l2 -> HList (HAppendListR '[] l2) Source # | |
HAppendList l l' => HAppendList (x ': l) l' Source # | |
Defined in Data.HList.HList hAppendList :: HList (x ': l) -> HList l' -> HList (HAppendListR (x ': l) l') Source # |
Alternative append
Historical append
The original HList code is included below. In both cases we had to program the algorithm twice, at the term and the type levels.
The class HAppend
class HAppend l l' l'' | l l' -> l'' where hAppend :: l -> l' -> l''
The instance following the normal append
instance HList l => HAppend HNil l l where hAppend HNil l = l instance (HList l, HAppend l l' l'') => HAppend (HCons x l) l' (HCons x l'') where hAppend (HCons x l) l' = HCons x (hAppend l l')
Reversing HLists
hReverse_ :: forall {l1 :: [Type]} {l3 :: [Type]}. HRevApp l1 ('[] :: [Type]) l3 => HList l1 -> HList l3 Source #
a version of hReverse
that does not allow the type
information to flow backwards
A nicer notation for lists
hEnd :: HList l -> HList l Source #
Note:
x :: HList a
- means:
forall a. x :: HList a
hEnd x
- means:
exists a. x :: HList a
List termination
class HBuild' l r where Source #
Instances
HReverse l l' => HBuild' l (HList l') Source # | |
(HReverse l lRev, HMapTaggedFn lRev l') => HBuild' l (Record l') Source # | This instance allows creating a Record with hBuild 3 |
(HRevAppR l ('[] :: [Type]) ~ lRev, HExtendRs lRev (Proxy ('[] :: [Type])) ~ Proxy l1, l' ~ l1) => HBuild' l (Proxy l') Source # | see |
HBuild' (a ': l) r => HBuild' l (a -> r) Source # | |
Defined in Data.HList.HList |
examples
The classes above allow the third (shortest) way to make a list (containing a,b,c) in this case
list = a `HCons` b `HCons` c `HCons` HNil list = a .*. b .*. c .*. HNil list = hEnd $ hBuild a b c
>>>
let x = hBuild True in hEnd x
H[True]
>>>
let x = hBuild True 'a' in hEnd x
H[True,'a']
>>>
let x = hBuild True 'a' "ok" in hEnd x
H[True,'a',"ok"]
hBuild can also produce a Record, such that
hBuild x y ^. from unlabeled
can also be produced using
hEndR
$ hBuild x y
historical
the show instance has since changed, but these uses of
hBuild
/hEnd
still work
HList> let x = hBuild True in hEnd x HCons True HNil
HList> let x = hBuild True 'a' in hEnd x HCons True (HCons 'a' HNil)
HList> let x = hBuild True 'a' "ok" in hEnd x HCons True (HCons 'a' (HCons "ok" HNil))
HList> hEnd (hBuild (Key 42) (Name "Angus") Cow (Price 75.5)) HCons (Key 42) (HCons (Name "Angus") (HCons Cow (HCons (Price 75.5) HNil)))
HList> hEnd (hBuild (Key 42) (Name "Angus") Cow (Price 75.5)) == angus True
folds
foldr
Consume a heterogenous list.
foldl
class HFoldl f (z :: *) xs (r :: *) where Source #
like foldl
>>>
hFoldl (uncurry $ flip (:)) [] (1 `HCons` 2 `HCons` HNil)
[2,1]
unfolds
unfold
Produce a heterogenous list. Uses the more limited
Apply
instead of App
since that's all that is needed for uses of this
function downstream. Those could in principle be re-written.
hUnfold :: forall {f} {a} {z :: [Type]}. (HUnfoldFD f (ApplyR f a) z, Apply f a) => f -> a -> HList z Source #
replicate
class HLengthEq es n => HReplicateFD (n :: HNat) e es | n e -> es, es -> n where Source #
Sometimes the result type can fix the type of the first argument:
>>>
hReplicate Proxy () :: HList '[ (), (), () ]
H[(),(),()]
However, with HReplicate all elements must have the same type, so it may be
easier to use HList2List
:
>>>
list2HList (repeat 3) :: Maybe (HList [Int, Int, Int])
Just H[3,3,3]
hReplicate :: Proxy n -> e -> HList es Source #
Instances
HReplicateFD 'HZero e ('[] :: [Type]) Source # | |
Defined in Data.HList.HList | |
(HReplicateFD n e es, e ~ e') => HReplicateFD ('HSucc n) e (e' ': es) Source # | |
Defined in Data.HList.HList |
type HReplicate n e = HReplicateFD n e (HReplicateR n e) Source #
type family HReplicateR (n :: HNat) (e :: k) :: [k] Source #
would be associated with HReplicate
except we want
it to work with e
of any kind, not just *
that you can
put into a HList. An "inverse" of HLength
Instances
type HReplicateR 'HZero (e :: k) Source # | |
Defined in Data.HList.HList | |
type HReplicateR ('HSucc n) (e :: k) Source # | |
Defined in Data.HList.HList |
class HLengthEq r n => HReplicateF (n :: HNat) f z r | r -> n where Source #
HReplicate produces lists that can be converted to ordinary lists
>>>
let two = hSucc (hSucc hZero)
>>>
let f = Fun' fromInteger :: Fun' Num Integer
>>>
:t applyAB f
applyAB f :: Num b => Integer -> b
>>>
hReplicateF two f 3
H[3,3]
>>>
hReplicateF Proxy f 3 :: HList [Int, Double, Integer]
H[3,3.0,3]
Instances
HReplicateF 'HZero f z ('[] :: [Type]) Source # | |
Defined in Data.HList.HList | |
(ApplyAB f z fz, HReplicateF n f z r') => HReplicateF ('HSucc n) f z (fz ': r') Source # | |
Defined in Data.HList.HList |
iterate
class HLengthEq r n => HIterate n f z r where Source #
This function behaves like iterate
, with an extra
argument to help figure out the result length
>>>
let three = hSucc (hSucc (hSucc hZero))
>>>
let f = Fun Just :: Fun '() Maybe
>>>
:t applyAB f
applyAB f :: a -> Maybe a
f is applied to different types:
>>>
hIterate three f ()
H[(),Just (),Just (Just ())]
It is also possible to specify the length later on,
as done with Prelude.iterate
>>>
let take3 x | _ <- hLength x `asTypeOf` three = x
>>>
take3 $ hIterate Proxy f ()
H[(),Just (),Just (Just ())]
concat
type HConcat xs = HConcatFD xs (HConcatR xs) Source #
Like concat
but for HLists of HLists.
Works in ghci... puzzling as what is different in doctest (it isn't
-XExtendedDefaultRules
)
>>>
let a = hEnd $ hBuild 1 2 3
>>>
let b = hEnd $ hBuild 'a' "abc"
>>>
hConcat $ hBuild a b
H[1,2,3,'a',"abc"]
traversing HLists
producing HList
map
It could be implemented with hFoldr
, as we show further below
hMap is written such that the length of the result list can be determined from the length of the argument list (and the other way around). Similarly, the type of the elements of the list is propagated in both directions too.
>>>
:set -XNoMonomorphismRestriction
>>>
let xs = 1 .*. 'c' .*. HNil
>>>
:t hMap (HJust ()) xs
hMap (HJust ()) xs :: Num y => HList '[HJust y, HJust Char]
These 4 examples show that the constraint on the length (2 in this case)
can be applied before or after the hMap
. That inference is independent of the
direction that type information is propagated for the individual elements.
>>>
let asLen2 xs = xs `asTypeOf` (undefined :: HList '[a,b])
>>>
let lr xs = asLen2 (applyAB (HMap HRead) xs)
>>>
let ls xs = asLen2 (applyAB (HMap HShow) xs)
>>>
let rl xs = applyAB (HMap HRead) (asLen2 xs)
>>>
let sl xs = applyAB (HMap HShow) (asLen2 xs)
>>>
:t lr
lr :: (Read ..., Read ...) => HList '[String, String] -> HList '[..., ...]
>>>
:t rl
rl :: (Read ..., Read ...) => HList '[String, String] -> HList '[..., ...]
>>>
:t ls
ls :: (Show ..., Show ...) => HList '[..., ...] -> HList '[String, String]
>>>
:t sl
sl :: (Show ..., Show ...) => HList '[..., ...] -> HList '[String, String]
HMap f |
hMap :: forall {a :: [Type]} {b :: [Type]} {r} {f}. (SameLength' a b, SameLength' b a, HMapAux r f a b) => f -> r a -> r b Source #
hMapL :: forall {a :: [Type]} {b :: [Type]} {f}. (SameLength' a b, SameLength' b a, HMapAux HList f a b) => f -> HList a -> HList b Source #
hMap constrained to HList
HMapL f |
class (SameLength a b, HMapAux r f a b) => HMapCxt r f a b Source #
Instances
(SameLength a b, HMapAux r f a b) => HMapCxt r f a b Source # | |
Defined in Data.HList.HList |
class HMapAux (r :: [*] -> *) f (x :: [*]) (y :: [*]) where Source #
hMapAux :: SameLength x y => f -> r x -> r y Source #
Instances
HMapAux HList (HFmap f) x y => HMapAux Record f x y Source # | |
(ApplyAB f (GetElemTy x) (GetElemTy y), IArray UArray (GetElemTy y), IArray UArray (GetElemTy x)) => HMapAux RecordU f x y Source # | |
HMapAux Variant f xs ys => HMapAux TIC f xs ys Source # | |
HMapAux HList f ('[] :: [Type]) ('[] :: [Type]) Source # | |
(ApplyAB f e e', HMapAux HList f l l', SameLength l l') => HMapAux HList f (e ': l) (e' ': l') Source # | |
(ApplyAB f te te', HMapCxt Variant f (l ': ls) (l' ': ls')) => HMapAux Variant f (te ': (l ': ls)) (te' ': (l' ': ls')) Source # | |
ApplyAB f te te' => HMapAux Variant f '[te] '[te'] Source # | |
alternative implementation
currently broken
MapCar f |
hMapMapCar :: HFoldr (MapCar f) (HList '[]) l l' => f -> HList l -> l' Source #
Same as hMap
only a different implementation.
appEndo . mconcat . map Endo
hComposeList :: HFoldr Comp (a -> a) l (t -> a) => HList l -> t -> a Source #
>>>
let xs = length .*. (+1) .*. (*2) .*. HNil
>>>
hComposeList xs "abc"
8
sequence
class (Applicative m, SameLength a b) => HSequence m a b | a -> b, m b -> a where Source #
A heterogeneous version of
sequenceA :: (Applicative m) => [m a] -> m [a]
Only now we operate on heterogeneous lists, where different elements
may have different types a
.
In the argument list of monadic values (m a_i),
although a_i may differ, the monad m
must be the same for all
elements. That's why we needed Data.HList.TypeCastGeneric2 (currently (~)).
The typechecker will complain
if we attempt to use hSequence on a HList of monadic values with different
monads.
The hSequence
problem was posed by Matthias Fischmann
in his message on the Haskell-Cafe list on Oct 8, 2006
http://www.haskell.org/pipermail/haskell-cafe/2006-October/018708.html
http://www.haskell.org/pipermail/haskell-cafe/2006-October/018784.html
Maybe
>>>
hSequence $ Just (1 :: Integer) `HCons` (Just 'c') `HCons` HNil
Just H[1,'c']
>>>
hSequence $ return 1 `HCons` Just 'c' `HCons` HNil
Just H[1,'c']
List
>>>
hSequence $ [1] `HCons` ['c'] `HCons` HNil
[H[1,'c']]
alternative implementation
hSequence2 :: forall {f} {l :: [Type]} {a}. (Applicative f, HFoldr (LiftA2 FHCons) (f (HList ('[] :: [Type]))) l (f a)) => HList l -> f a Source #
hSequence2
is not recommended over hSequence
since it possibly doesn't
allow inferring argument types from the result types. Otherwise this version
should do exactly the same thing.
The DataKinds version needs a little help to find the type of the return HNil, unlike the original version, which worked just fine as
hSequence l = hFoldr ConsM (return HNil) l
producing homogenous lists
map (no sequencing)
This one we implement via hFoldr
Mapcar f |
hMapOut :: forall f e l. HMapOut f l e => f -> HList l -> [e] Source #
compare hMapOut f
with hList2List
. hMap
f
mapM
hMapM_ :: (Monad m, HMapOut f l (m ())) => f -> HList l -> m () Source #
GHC doesn't like its own type.
hMapM_ :: forall m a f e. (Monad m, HMapOut f a (m e)) => f -> a -> m ()
Without explicit type signature, it's Ok. Sigh. Anyway, Hugs does insist on a better type. So we restrict as follows:
Ensure a list to contain HNats only
type family HNats (l :: [*]) :: [HNat] Source #
We do so constructively, converting the HList whose elements are Proxy HNat to [HNat]. The latter kind is unpopulated and is present only at the type level.
Membership tests
class HMember (e1 :: k) (l :: [k]) (b :: Bool) | e1 l -> b Source #
Check to see if an HList contains an element with a given type This is a type-level only test
type family HMemberP pred e1 (l :: [*]) :: Bool Source #
The following is a similar type-only membership test It uses the user-supplied curried type equality predicate pred
Another type-level membership test
class HMemberM (e1 :: k) (l :: [k]) (r :: Maybe [k]) | e1 l -> r Source #
Check to see if an element e occurs in a list l If not, return 'Nothing If the element does occur, return 'Just l1 where l1 is a type-level list without e
Staged equality for lists
removed. use Typeable instead
Find an element in a set based on HEq
class HFind1 e l l n => HFind (e :: k) (l :: [k]) (n :: HNat) | e l -> n Source #
It is a pure type-level operation
Instances
HFind1 e l l n => HFind (e :: k) (l :: [k]) n Source # | |
Defined in Data.HList.HList |
class HFind1 (e :: k) (l :: [k]) (l0 :: [k]) (n :: HNat) | e l -> n Source #
Instances
Fail (FieldNotFound e1 l0) => HFind1 (e1 :: k) ('[] :: [k]) (l0 :: [k]) 'HZero Source # | |
Defined in Data.HList.HList | |
(HEq e1 e2 b, HFind2 b e1 l l0 n) => HFind1 (e1 :: a) (e2 ': l :: [a]) (l0 :: [a]) n Source # | |
Defined in Data.HList.HList |
Membership test based on type equality
class HTMember e (l :: [*]) (b :: Bool) | e l -> b Source #
could be an associated type if HEq had one
Intersection based on HTMember
class HTIntersect l1 l2 l3 | l1 l2 -> l3 where Source #
Instances
HTIntersect ('[] :: [Type]) l ('[] :: [Type]) Source # | |
Defined in Data.HList.HList | |
(HTMember h l1 b, HTIntersectBool b h t l1 l2) => HTIntersect (h ': t) l1 l2 Source # | |
Defined in Data.HList.HList |
class HTIntersectBool (b :: Bool) h t l1 l2 | b h t l1 -> l2 where Source #
Instances
HTIntersect t l1 l2 => HTIntersectBool 'False h t l1 l2 Source # | |
Defined in Data.HList.HList | |
HTIntersect t l1 l2 => HTIntersectBool 'True h t l1 (h ': l2) Source # | |
Defined in Data.HList.HList |
Convert between heterogeneous lists and homogeneous ones
class HList2List l e | l -> e where Source #
hMapOut id
is similar, except this function is restricted
to HLists that actually contain a value (so the list produced
will be nonempty). This restriction allows adding a functional
dependency, which means that less type annotations can be necessary.
hList2List :: HList l -> [e] Source #
list2HListSuffix :: [e] -> Maybe (HList l, [e]) Source #
Instances
HList2List (e' ': l) e => HList2List (e ': (e' ': l)) e Source # | |
Defined in Data.HList.HList hList2List :: HList (e ': (e' ': l)) -> [e] Source # list2HListSuffix :: [e] -> Maybe (HList (e ': (e' ': l)), [e]) Source # | |
HList2List '[e] e Source # | |
Defined in Data.HList.HList hList2List :: HList '[e] -> [e] Source # list2HListSuffix :: [e] -> Maybe (HList '[e], [e]) Source # |
list2HList :: HList2List l e => [e] -> Maybe (HList l) Source #
listAsHList :: forall {p} {f} {l :: [Type]} {e} {l :: [Type]} {e}. (Choice p, Applicative f, HList2List l e, HList2List l e) => p (HList l) (f (HList l)) -> p [e] (f [e]) Source #
Prism [s] [t] (HList s) (HList t)
listAsHList' :: forall {p} {f} {l :: [Type]} {e}. (Choice p, Applicative f, HList2List l e) => p (HList l) (f (HList l)) -> p [e] (f [e]) Source #
Prism' [a] (HList s)
where s ~ HReplicateR n a
With HMaybe
Turn list in a list of justs
class FromHJustR (ToHJustR l) ~ l => ToHJust l where Source #
the same as map Just
>>>
toHJust (2 .*. 'a' .*. HNil)
H[HJust 2,HJust 'a']
>>>
toHJust2 (2 .*. 'a' .*. HNil)
H[HJust 2,HJust 'a']
toHJust2 :: (HMapCxt r (HJust ()) a b, ToHJust a, b ~ ToHJustR a) => r a -> r b Source #
alternative implementation. The Apply instance is in Data.HList.FakePrelude. A longer type could be inferred.
Extract justs from list of maybes
class FromHJustR (ToHJustR l) ~ l => FromHJust l where Source #
type FromHJustR l :: [*] Source #
Instances
FromHJust ('[] :: [Type]) Source # | |
Defined in Data.HList.HList type FromHJustR '[] :: [Type] Source # | |
FromHJust l => FromHJust (HJust e ': l) Source # | |
Defined in Data.HList.HList type FromHJustR (HJust e ': l) :: [Type] Source # | |
FromHJust l => FromHJust (HNothing ': l) Source # | |
Defined in Data.HList.HList type FromHJustR (HNothing ': l) :: [Type] Source # |
alternative implementation
fromHJust2 :: HMapCxt r HFromJust a b => r a -> r b Source #
This implementation is shorter.
Annotated lists
HAddTag t |
hAddTag :: forall {a :: [Type]} {b :: [Type]} {r} {t}. (SameLength' a b, SameLength' b a, HMapAux r (HAddTag t) a b) => t -> r a -> r b Source #
hRmTag :: forall {a :: [Type]} {b :: [Type]} {r}. (SameLength' a b, SameLength' b a, HMapAux r HRmTag a b) => r a -> r b Source #
hFlag :: forall {a :: [Type]} {b :: [Type]} {r}. (SameLength' a b, SameLength' b a, HMapAux r (HAddTag (Proxy 'True)) a b) => r a -> r b Source #
Annotate list with a type-level Boolean
hFlag :: HMapCxt (HAddTag (Proxy True)) l r => HList l -> HList r
Splitting by HTrue and HFalse
Analogus to Data.List.partition
snd
. See also HPartition
>>>
let (.=.) :: p x -> y -> Tagged x y; _ .=. y = Tagged y
>>>
hSplit $ hTrue .=. 2 .*. hTrue .=. 3 .*. hFalse .=. 1 .*. HNil
(H[2,3],H[1])
it might make more sense to instead have LVPair Bool e
instead of (e, Proxy Bool)
since the former has the same
runtime representation as e
Splitting by Length
class (HLengthEq xs n, HAppendList1 xs ys xsys) => HSplitAt (n :: HNat) xsys xs ys | n xsys -> xs ys, xs ys -> xsys, xs -> n where Source #
setup
>>>
let two = hSucc (hSucc hZero)
>>>
let xsys = hEnd $ hBuild 1 2 3 4
If a length is explicitly provided, the resulting lists are inferred
>>>
hSplitAt two xsys
(H[1,2],H[3,4])
>>>
let sameLength_ :: SameLength a b => r a -> r b -> r a; sameLength_ = const
>>>
let len2 x = x `sameLength_` HCons () (HCons () HNil)
If the first chunk of the list (a) has to be a certain length, the type of the Proxy argument can be inferred.
>>>
case hSplitAt Proxy xsys of (a,b) -> (len2 a, b)
(H[1,2],H[3,4])
class HSplitAt1 accum (n :: HNat) xsys xs ys | accum n xsys -> xs ys where Source #
helper for HSplitAt
class (SameLength' (HReplicateR n ()) xs, HLengthEq1 xs n, HLengthEq2 xs n) => HLengthEq (xs :: [*]) (n :: HNat) | xs -> n Source #
a better way to write HLength xs ~ n
because:
- it works properly with ghc-7.10 (probably another example of ghc bug #10009)
- it works backwards a bit in that if
n
is known, thenxs
can be refined:
>>>
undefined :: HLengthEq xs HZero => HList xs
H[]
Instances
(SameLength' (HReplicateR n ()) xs, HLengthEq1 xs n, HLengthEq2 xs n) => HLengthEq xs n Source # | |
Defined in Data.HList.HList |
class HLengthEq1 (xs :: [*]) n Source #
Instances
xxs ~ ('[] :: [Type]) => HLengthEq1 xxs 'HZero Source # | |
Defined in Data.HList.HList | |
(HLengthEq xs n, xxs ~ (x ': xs)) => HLengthEq1 xxs ('HSucc n :: HNat) Source # | |
Defined in Data.HList.HList |
class HLengthEq2 (xs :: [*]) n | xs -> n Source #
Instances
zero ~ 'HZero => HLengthEq2 ('[] :: [Type]) (zero :: HNat) Source # | |
Defined in Data.HList.HList | |
(HLengthEq xs n, sn ~ 'HSucc n) => HLengthEq2 (x ': xs) (sn :: HNat) Source # | |
Defined in Data.HList.HList |
class HLengthGe (xs :: [*]) (n :: HNat) Source #
HLengthGe xs n
says that HLength xs >= n
.
unlike the expression with a type family HLength,
ghc assumes xs ~ (aFresh ': bFresh)
when given a
constraint HLengthGe xs (HSucc HZero)
class HStripPrefix xs xsys ys => HAppendList1 (xs :: [k]) (ys :: [k]) (xsys :: [k]) | xs ys -> xsys, xs xsys -> ys Source #
HAppendList1 xs ys xsys
is the type-level way of saying xs ++ ys == xsys
used by HSplitAt
Instances
HAppendList1 ('[] :: [k]) (ys :: [k]) (ys :: [k]) Source # | |
Defined in Data.HList.HList | |
HAppendList1 xs ys zs => HAppendList1 (x ': xs :: [a]) (ys :: [a]) (x ': zs :: [a]) Source # | |
Defined in Data.HList.HList |
class HStripPrefix xs xsys ys | xs xsys -> ys Source #
analog of stripPrefix
Instances
HStripPrefix ('[] :: [k2]) (ys :: k1) (ys :: k1) Source # | |
Defined in Data.HList.HList | |
(x' ~ x, HStripPrefix xs xsys ys) => HStripPrefix (x' ': xs :: [a]) (x ': xsys :: [a]) (ys :: k) Source # | |
Defined in Data.HList.HList |
take
drop
Conversion to and from tuples
class HTuple v t | v -> t, t -> v where Source #
Instances
HTuple ('[] :: [Type]) () Source # | |
Defined in Data.HList.HList | |
HTuple '[a, b] (a, b) Source # | |
Defined in Data.HList.HList | |
HTuple '[a, b, c] (a, b, c) Source # | |
Defined in Data.HList.HList | |
HTuple '[a, b, c, d] (a, b, c, d) Source # | |
Defined in Data.HList.HList | |
HTuple '[a, b, c, d, e] (a, b, c, d, e) Source # | |
Defined in Data.HList.HList | |
HTuple '[a, b, c, d, e, f] (a, b, c, d, e, f) Source # | |
Defined in Data.HList.HList |
hTuple :: forall {p} {f} {v :: [Type]} {a} {v :: [Type]} {b}. (Profunctor p, Functor f, HTuple v a, HTuple v b) => p a (f b) -> p (HList v) (f (HList v)) Source #
Iso (HList v) (HList v') a b
hTuple' :: forall {p} {f} {v :: [Type]} {a}. (Profunctor p, Functor f, HTuple v a) => p a (f a) -> p (HList v) (f (HList v)) Source #
Iso' (HList v) a
class HInits1 a b | a -> b, b -> a where Source #
behaves like tail . inits
partition
class HPartitionEq f x1 xs xi xo | f x1 xs -> xi xo where Source #
HPartitionEq f x1 xs xi xo
is analogous to
(xi,xo) = partition (f x1) xs
where f
is a "function" passed in using it's instance of HEqBy
Instances
HPartitionEq (f :: k1) (x1 :: k2) ('[] :: [Type]) ('[] :: [Type]) ('[] :: [Type]) Source # | |
Defined in Data.HList.HList | |
(HEqBy f x1 x b, HPartitionEq1 b f x1 x xs xi xo) => HPartitionEq (f :: k) (x1 :: Type) (x ': xs) xi xo Source # | |
Defined in Data.HList.HList |
class HPartitionEq1 (b :: Bool) f x1 x xs xi xo | b f x1 x xs -> xi xo where Source #
Instances
HPartitionEq f x1 xs xi xo => HPartitionEq1 'False (f :: k1) (x1 :: k2) x xs xi (x ': xo) Source # | |
HPartitionEq f x1 xs xi xo => HPartitionEq1 'True (f :: k1) (x1 :: k2) x xs (x ': xi) xo Source # | |
groupBy
class HGroupBy (f :: t) (as :: [*]) (gs :: [*]) | f as -> gs, gs -> as where Source #
span
class HSpanEqBy (f :: t) (x :: *) (y :: [*]) (fst :: [*]) (snd :: [*]) | f x y -> fst snd, fst snd -> y where Source #
HSpanEq x y fst snd
is analogous to (fst,snd) =
span
(== x) y
Instances
(HSpanEqBy1 f x y fst snd, HAppendListR fst snd ~ y) => HSpanEqBy (f :: t) x y fst snd Source # | |
class HSpanEqBy1 (f :: t) (x :: *) (y :: [*]) (i :: [*]) (o :: [*]) | f x y -> i o where Source #
Instances
HSpanEqBy1 (f :: t) x ('[] :: [Type]) ('[] :: [Type]) ('[] :: [Type]) Source # | |
Defined in Data.HList.HList | |
(HEqBy f x y b, HSpanEqBy2 b f x y ys i o) => HSpanEqBy1 (f :: t) x (y ': ys) i o Source # | |
Defined in Data.HList.HList |
class HSpanEqBy2 (b :: Bool) (f :: t) (x :: *) (y :: *) (ys :: [*]) (i :: [*]) (o :: [*]) | b f x y ys -> i o where Source #
Instances
HSpanEqBy2 'False (f :: t) x y ys ('[] :: [Type]) (y ': ys) Source # | |
Defined in Data.HList.HList | |
HSpanEqBy1 f x zs i o => HSpanEqBy2 'True (f :: t) x y zs (y ': i) o Source # | |
Defined in Data.HList.HList |
zip
see alternative implementations in Data.HList.HZip
Monoid instance
helper functions
data ConstMempty Source #
Instances
(x ~ Proxy y, Monoid y) => ApplyAB ConstMempty x y Source # | |
Defined in Data.HList.HList applyAB :: ConstMempty -> x -> y Source # |
data UncurryMappend Source #
Instances
(aa ~ (a, a), Monoid a) => ApplyAB UncurryMappend aa a Source # | |
Defined in Data.HList.HList applyAB :: UncurryMappend -> aa -> a Source # |
data UncurrySappend Source #
Instances
(aa ~ (a, a), Semigroup a) => ApplyAB UncurrySappend aa a Source # | |
Defined in Data.HList.HList applyAB :: UncurrySappend -> aa -> a Source # |