packages feed

HList 0.2.1 → 0.2.2

raw patch · 28 files changed

+642/−340 lines, 28 filesdep +template-haskellPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: template-haskell

API changes (from Hackage documentation)

- Data.HList.HZip: class HZippable x y
- Data.HList.HZip: instance [overlap ok] (HZippable l l') => HZippable (HCons e l) (HCons e' l')
- Data.HList.HZip: instance [overlap ok] HZippable HNil HNil
+ Data.HList.GhcSyntax: (.+.) :: (HExtend (Proxy e) l l') => e -> l -> l'
+ Data.HList.GhcSyntax: (.-.) :: (H2ProjectByLabels (HCons e HNil) r _r' r') => Record r -> e -> Record r'
+ Data.HList.GhcSyntax: (.<++.) :: (HLeftUnion r r' r'') => r -> r' -> r''
+ Data.HList.GhcSyntax: (.<.) :: (HasField t t2 t1, HUpdateAtHNat n (LVPair t t1) t2 l', HFind t ls n, RecordLabels t2 ls) => LVPair t t1 -> Record t2 -> Record l'
+ Data.HList.GhcSyntax: (.@.) :: (HUpdateAtHNat n (LVPair t t1) t2 l', HFind t ls n, RecordLabels t2 ls) => LVPair t t1 -> Record t2 -> Record l'
+ Data.HList.GhcSyntax: (.^.) :: (HUpdateAtHNat n (LVPair t t1) t2 l', HFind t ls n, RecordLabels t2 ls, HasField t t2 (Proxy t1)) => LVPair t t1 -> Record t2 -> Record l'
+ Data.HList.MakeLabels: instance [overlap ok] ReplaceSyntax Dec
+ Data.HList.MakeLabels: instance [overlap ok] ReplaceSyntax Exp
+ Data.HList.MakeLabels: instance [overlap ok] ReplaceSyntax Type
+ Data.HList.MakeLabels: instance [overlap ok] ReplaceSyntax [Dec]
+ Data.HList.MakeLabels: label :: String -> Q [Dec]
+ Data.HList.MakeLabels: makeLabels :: [String] -> Q [Dec]
+ Data.HList.Record: hDeleteAtLabel :: (H2ProjectByLabels (HCons e HNil) t t1 t2) => e -> Record t -> Record t2
+ Data.HList.Record: hProjectByLabels2 :: (H2ProjectByLabels ls t t1 t2, HRLabelSet t1, HRLabelSet t2) => ls -> Record t -> (Record t1, Record t2)
+ Data.HList.Record: hRenameLabel :: (HRLabelSet (HCons (LVPair l v) t2), HasField e t1 v, H2ProjectByLabels (HCons e HNil) t1 t t2) => e -> l -> Record t1 -> Record (HCons (LVPair l v) t2)
+ Data.HList.Record: hTPupdateAtLabel :: (HasField l t a, HUpdateAtHNat n (LVPair l a) t l', HFind l ls n, RecordLabels t ls) => l -> a -> Record t -> Record l'
+ Data.HList.Record: hUpdateAtLabel :: (HUpdateAtHNat n (LVPair l v) t l', HFind l ls n, RecordLabels t ls) => l -> v -> Record t -> Record l'

Files

Data/HList.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE MagicHash #-}-{-+{- | OOHaskell (C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke  This module gathers the API that we need for OOP in Haskell.  We
Data/HList/CommonMain.hs view
@@ -1,4 +1,4 @@-{-+{- |     The HList library 
Data/HList/FakePrelude.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE EmptyDataDecls, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, UndecidableInstances #-} -{-+{- |    The HList library     (C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke@@ -13,7 +13,7 @@  {-----------------------------------------------------------------------------} --- Type-level Booleans+-- * Booleans  data HTrue; hTrue :: HTrue; hTrue = undefined data HFalse; hFalse :: HFalse; hFalse = undefined@@ -22,7 +22,7 @@ instance Show HFalse where show _ = "HFalse"  --- Conjunction of type-level Booleans+-- **  Conjunction  class (HBool t, HBool t', HBool t'') => HAnd t t' t'' | t t' -> t''  where@@ -45,7 +45,7 @@   hAnd _ _ = hTrue  --- Disjunction of type-level Booleans+-- ** Disjunction  class (HBool t, HBool t', HBool t'') => HOr t t' t'' | t t' -> t''  where@@ -68,7 +68,7 @@   hOr _ _ = hTrue  --- Type-level conditional+-- ** Conditional  class HBool t => HCond t x y z | t x y -> z  where@@ -89,7 +89,7 @@  {-----------------------------------------------------------------------------} --- Type-level naturals+-- * Naturals  data HZero data HSucc n@@ -123,7 +123,7 @@  {-----------------------------------------------------------------------------} --- Type-level maybies+-- * Maybies  data HNothing  = HNothing  deriving Show data HJust x   = HJust x   deriving Show@@ -131,11 +131,10 @@  {-----------------------------------------------------------------------------} --- Equality for types+-- * Equality for types  class HBool b => HEq x y b | x y -> b - -- Equality instances for naturals  instance HEq HZero HZero HTrue@@ -150,9 +149,12 @@  {-----------------------------------------------------------------------------} --- Staged equality---  - Establish type equality statically---  - Establish remaining value-level equality dynamically+-- * Staged equality+-- |+--+--  * Establish type equality statically+--+--  * Establish remaining value-level equality dynamically  class HStagedEq x y  where@@ -161,7 +163,7 @@  {-----------------------------------------------------------------------------} --- Less than+-- | Less than  class HBool b => HLt x y b | x y -> b @@ -180,8 +182,10 @@  {-----------------------------------------------------------------------------} --- A predicate for type equality+-- | A predicate for type equality+-- -- There are different implementations.+-- -- See imports in Main*.hs  class HBool b => TypeEq x y b | x y -> b@@ -199,7 +203,7 @@  {-----------------------------------------------------------------------------} --- Type-safe cast+-- * Type-safe cast  class TypeCast x y | x -> y, y -> x  where@@ -208,7 +212,7 @@  {-----------------------------------------------------------------------------} --- A phantom type for type proxies+-- * A phantom type for type proxies  data Proxy e instance Show (Proxy e) where show _ = "Proxy"@@ -225,7 +229,7 @@  {-----------------------------------------------------------------------------} --- Type equality and disequality+-- * Type equality and disequality  class TypeEqTrue x y class TypeEqFalse x y@@ -239,7 +243,7 @@  {-----------------------------------------------------------------------------} --- Subtyping+-- * Subtyping  class SubType l l' @@ -249,7 +253,9 @@  {-----------------------------------------------------------------------------} --- A class without instances for explicit failure+-- * Error messages++-- | A class without instances for explicit failure class Fail x  
Data/HList/GhcRecord.hs view
@@ -7,14 +7,14 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FunctionalDependencies #-} -{-+{- |    The HList library     (C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke     Extensible records -- operations that (may) require GHC -   See Record.hs for the base module.+   See "Data.HList.Record" for the base module. -}  module Data.HList.GhcRecord where@@ -28,7 +28,8 @@  {-----------------------------------------------------------------------------} --- A variation on update.+-- | A variation on update.+-- -- Replace a proxy by a value of the proxied type. -- The signature is inferred hUnproxyLabel :: (HUpdateAtHNat n (LVPair l a) t l', HFind l ls n,@@ -44,7 +45,7 @@  {-----------------------------------------------------------------------------} --- Test for values; refuse proxies+-- | Test for values; refuse proxies  hasNoProxies :: HasNoProxies r              => Record r -> ()@@ -61,8 +62,8 @@  {-----------------------------------------------------------------------------} --- Narrow a record to a different record type-+-- | Narrow a record to a different record type+-- -- First is the `monadic' version, which returns the `failure indictator' -- (HNothing) if the narrowing fails because the source does not have -- all the fields for the target.@@ -119,7 +120,7 @@  {-----------------------------------------------------------------------------} --- Narrow two records to their least-upper bound+-- | Narrow two records to their least-upper bound  class LubNarrow a b c | a b -> c  where@@ -142,7 +143,7 @@  {-----------------------------------------------------------------------------} --- List constructors that also LUB together+-- | List constructors that also LUB together  data NilLub nilLub :: NilLub@@ -165,7 +166,7 @@  {-----------------------------------------------------------------------------} --- Extension of lubNarrow to a heterogeneous list+-- | Extension of lubNarrow to a heterogeneous list  class HLub l e | l -> e  where@@ -196,18 +197,23 @@   {-----------------------------------------------------------------------------}--- Record equivalence modulo field order+-- | Record equivalence modulo field order+-- -- Decide if two records r1 and r2 are identical or differ only in the order -- of their fields.+-- -- If the two record types are indeed equivalent, return the witness of -- their equivalence, (HJust (r1->r2,r2->r1)). If they are not equivalent, -- return HNothing+-- -- The function equivR does not examine the values of its arguments: -- it needs only their types.-+--+-- -- The algorithm is simple: two records are equivalent if one can be narrowed -- to the other, and vice versa. The narrowing coercions are the desired -- witnesses.+-- -- The obvious optimization is to check first if two records are of the same -- type. That requires TypeEq however. Perhaps we shouldn't use it here. -- Use of the record narrowing tacitly assumes that the label of a record
Data/HList/GhcSyntax.hs view
@@ -1,7 +1,6 @@ {-# LANGUAGE TypeOperators #-}-{-# OPTIONS_GHC -fno-warn-missing-signatures #-} {-# LANGUAGE FlexibleContexts #-}-{-+{- |    (C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke     Some dedicated infix operators at the type and the value level.@@ -13,123 +12,135 @@ import Data.HList.HListPrelude import Data.HList.Record import Data.HList.GhcRecord+import Data.HList.HArray   {-----------------------------------------------------------------------------} --- Convenience notation for type sequences+-- * For types  infixr 2 :*: infixr 2 .*.  type e :*: l = HCons e l -{-| -  (.*.) -- Add a field to a record. Analagous to (++) for-           lists. +infixr 4 :=:+type l :=: v = LVPair l v -  record .*. field1-         .*. field2---}-(.*.) :: HExtend e l l' => e -> l -> l'-(.*.) =  hExtend+infixr 4 .=.   {-----------------------------------------------------------------------------} --- Convenience notation for records--- Many signatures are deliberately omitted. They should be inferred.--- There is no point of writing the same thing in terms and in types.+-- * For records -infixr 4 :=:-type l :=: v = LVPair l v+{-| -infixr 4 .=.+  [@(.*.)@]+           Add a field to a record. Analagous to (++) for+           lists.++  > record .*. field1+  >        .*. field2++-}+(.*.) :: HExtend e l l' => e -> l -> l'+(.*.) =  hExtend+ {-| -  (.=.) -- Create a value with the given label. Analagous to a data-           constructor such as 'Just', 'Left', or 'Right'. Higher fixity-           than record-modification operations like (.*.), (.-.), etc. to-           support expression like the below w/o parentheses:+  Create a value with the given label. Analagous to a data+  constructor such as 'Just', 'Left', or 'Right'. Higher fixity+  than record-modification operations like (.*.), (.-.), etc. to+  support expression like the below w/o parentheses: -  label1 .=. value1 .*. -  label2 .=. value2 .*. -  emptyRecord+  > label1 .=. value1 .*.+  > label2 .=. value2 .*.+  > emptyRecord ---}+-} (.=.) :: l -> v -> LVPair l v l .=. v = newLVPair l v  infixr 9 .!. {-|-  (.!.) -- Lookup a value in a record, by its label. Analagous to (!!), the-           list indexing operation. Highest fixity, like (!!).+  Lookup a value in a record, by its label. Analagous to (!!), the+  list indexing operation. Highest fixity, like (!!). -  record1 .*. label1 .=. record2 .!. label1-          .*. label2 .=. record2 .!. label2---}+  > record1 .*. label1 .=. record2 .!. label1+  >         .*. label2 .=. record2 .!. label2++-} (.!.) :: (HasField l r v) => r -> l -> v r .!. l =  hLookupByLabel l r  infixl 2 .-. {-|-  (.-.) -- Remove a field from a record. At the same-           level as other record modification options (.*.). Analagous-           to (\\) in lists.+  Remove a field from a record. At the same+  level as other record modification options (.*.). Analagous+  to (\\) in lists. -  record1 .-. label1+  > record1 .-. label1 -  label1 .=. value1 .*. -  label2 .=. value2 .-.-  label2 .*. -  emptyRecord +  > label1 .=. value1 .*.+  > label2 .=. value2 .-.+  > label2 .*.+  > emptyRecord -  label1 .=. value1 .-.-  label1 .*. -  label2 .=. value2 .*. -  emptyRecord +  > label1 .=. value1 .-.+  > label1 .*.+  > label2 .=. value2 .*.+  > emptyRecord -  record1 .*. label1 .=. record2 .!. label1-          .*. label2 .=. record2 .!. label2 -          .-. label1---}+  > record1 .*. label1 .=. record2 .!. label1+  >         .*. label2 .=. record2 .!. label2+  >         .-. label1++-}+(.-.) :: (H2ProjectByLabels (HCons e HNil) r _r' r') =>+    Record r -> e -> Record r' r .-. l =  hDeleteAtLabel l r  infixr 2 .@. {-|-  (.@.) -- Update a field with a particular value.-           Same fixity as (.*.) so that extensions and updates can be chained.-           There is no real list analogue, since there is no Prelude defined-           update. -  label1 .=. value1 .@. record1 +  Update a field with a particular value.+  Same fixity as (.*.) so that extensions and updates can be chained.+  There is no real list analogue, since there is no Prelude defined+  update. +  > label1 .=. value1 .@. record1+ -}+(.@.) :: (HUpdateAtHNat n (LVPair t t1) t2 l',HFind t ls n,RecordLabels t2 ls) =>LVPair t t1 -> Record t2 -> Record l' f@(LVPair v) .@. r  =  hUpdateAtLabel (labelLVPair f) v r  infixr 2 .^. {-|--  (.^.) -- This is a variation on updating (according to GhcRecord.hs),-           so use the same fixity as (.\@.).+  This is a variation on updating (according to GhcRecord.hs),+  so use the same fixity as (.\@.). -}+(.^.) :: (HUpdateAtHNat n (LVPair t t1) t2 l',HFind t ls n,RecordLabels t2 ls,HasField t t2 (Proxy t1)) =>LVPair t t1 -> Record t2 -> Record l' f@(LVPair v) .^. r = hUnproxyLabel (labelLVPair f) v r  infixr 2 .<.-{-| -  (.<.) -- Another variation on update, so give it the same fixity as (.\@.).+{-|+  Another variation on update, so give it the same fixity as (.\@.).  -}+(.<.) :: (HasField t t2 t1,HUpdateAtHNat n (LVPair t t1) t2 l',HFind t ls n,RecordLabels t2 ls) =>LVPair t t1 -> Record t2 -> Record l' f@(LVPair v) .<. r = hTPupdateAtLabel (labelLVPair f) v r  infixl 1 .<++. {-|-  (.<++.) -- Similar to list append, so give this slightly lower fixity than-             (.*.), so we can write:+  Similar to list append, so give this slightly lower fixity than+  (.*.), so we can write: -   field1 .=. value .*. record1 .<++. record2+   > field1 .=. value .*. record1 .<++. record2+ -}+(.<++.) ::  (HLeftUnion r r' r'') => r -> r' -> r'' r .<++. r' = hLeftUnion r r'  @@ -143,9 +154,10 @@ type e :+: l = HCons (Proxy e) l  {-|-  (.+.) -- Type-indexed rows append. Very similar to .*., so -           keep the same fixity.+  Type-indexed rows append. Very similar to (.*.), so+  keep the same fixity. -}+(.+.) ::  (HExtend (Proxy e) l l') => e -> l -> l' e .+. r = hExtend (toProxy e) r  
Data/HList/HArray.hs view
@@ -1,7 +1,7 @@ {-# OPTIONS_GHC -fno-warn-missing-signatures #-} {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances,   FlexibleContexts, UndecidableInstances #-}-{-+{- |    The HList library     (C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke@@ -17,7 +17,7 @@  {-----------------------------------------------------------------------------} --- A lookup operation+-- * Lookup  class HNat n => HLookupByHNat n l e | n l -> e  where@@ -35,7 +35,7 @@  {-----------------------------------------------------------------------------} --- A delete operation+-- * Delete  class HNat n => HDeleteAtHNat n l l' | n l -> l'  where@@ -53,7 +53,7 @@  {-----------------------------------------------------------------------------} --- An update operation+-- * Update  class HNat n => HUpdateAtHNat n e l l' | n e l -> l', l' n -> e  where@@ -72,10 +72,13 @@  {-----------------------------------------------------------------------------} --- Splitting an array according to indices+-- * Splitting+-- | Splitting an array according to indices+-- -- Signature is inferred:--- hSplitByHNats :: (HSplitByHNats' ns l' l'1 l'', HMap (HAddTag HTrue) l l') =>---                ns -> l -> (l'1, l'')+--+--  > hSplitByHNats :: (HSplitByHNats' ns l' l'1 l'', HMap (HAddTag HTrue) l l') =>+--  >               ns -> l -> (l'1, l'') hSplitByHNats ns l = hSplitByHNats' ns (hFlag l)  class HNats ns => HSplitByHNats' ns l l' l'' | ns l -> l' l''@@ -104,7 +107,7 @@  {-----------------------------------------------------------------------------} --- Another projection operation+-- * Projection  class HNats ns => HProjectByHNats ns l l' | ns l -> l'  where@@ -130,7 +133,7 @@  {-----------------------------------------------------------------------------} --- The complement of projection+-- * Complement of Projection  class HProjectAwayByHNats ns l l' | ns l -> l'  where@@ -153,7 +156,8 @@  {-----------------------------------------------------------------------------} --- Generate naturals from 1 to x - 1+-- * Enumerate naturals+-- | from 1 to x - 1  class HBetween x y | x -> y  where@@ -173,7 +177,7 @@   hBetween x = hBetween (hPred x) `hAppend` HCons (hPred x) HNil  --- Set-difference on naturals+-- * Set-difference on naturals  class HDiff x y z | x y -> z  where@@ -195,7 +199,8 @@          z  = hDiff x y  --- Membership test for types with HOrd instances+-- * Membership test for types with 'HOrd' instances+-- | -- This special type equality/comparison is entirely pure!  class HOrdMember e l b | e l -> b@@ -220,7 +225,7 @@  {-----------------------------------------------------------------------------} --- Length operation+-- * Length  class (HList l, HNat n) => HLength l n | l -> n instance HLength HNil HZero@@ -233,7 +238,7 @@  {-----------------------------------------------------------------------------} --- Bounded lists+-- * Bounded lists  class HMaxLength l s instance (HLength l s', HLt s' (HSucc s) HTrue) => HMaxLength l s
Data/HList/HListPrelude.hs view
@@ -1,12 +1,16 @@ {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances,   UndecidableInstances, FlexibleContexts #-} -{-+{- |    The HList library     (C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke     Basic declarations for typeful heterogeneous lists.++   Excuse the unstructured haddocks: while there are many declarations here+   some are alternative implementations should be grouped, and the definitions+   here are analgous to many list functions in the "Prelude".  -}  module Data.HList.HListPrelude where@@ -15,7 +19,7 @@  {-----------------------------------------------------------------------------} --- Heterogeneous type sequences+-- * Heterogeneous type sequences  data HNil      = HNil      deriving (Eq,Show,Read) data HCons e l = HCons e l deriving (Eq,Show,Read)@@ -23,7 +27,7 @@  {-----------------------------------------------------------------------------} --- The set of all types of heterogeneous lists+-- * The set of all types of heterogeneous lists  class HList l instance HList HNil@@ -32,7 +36,7 @@  {-----------------------------------------------------------------------------} --- Public constructors+-- * Public constructors  hNil  :: HNil hNil  =  HNil@@ -43,7 +47,7 @@  {-----------------------------------------------------------------------------} --- Basic list functions+-- * Basic list functions  class HHead l h | l -> h  where@@ -65,7 +69,7 @@  {-----------------------------------------------------------------------------} --- A class for extension+-- * A class for extension  class HExtend e l l' | e l -> l', l' -> e l  where@@ -82,23 +86,23 @@  {-----------------------------------------------------------------------------} --- Appending HLists+-- * Appending HLists --- The normal append for comparison+-- | The normal append for comparison  append :: [a] -> [a] -> [a] append [] l = l append (x:l) l' = x : append l l'  --- The class HAppend+-- | The class HAppend  class HAppend l l' l'' | l l' -> l''  where   hAppend :: l -> l' -> l''  --- The instance following the normal append+-- | The instance following the normal append  instance HList l => HAppend HNil l l  where@@ -112,7 +116,7 @@  {-----------------------------------------------------------------------------} --- Reversing HLists+-- * Reversing HLists  class HReverse l1 l2 | l1 -> l2, l2 -> l1  where@@ -140,7 +144,7 @@   hReverse' l1 (HCons a l2') = hReverse' (HCons a l1) l2'  --- Naive HReverse+-- ** Naive HReverse  class NaiveHReverse l l' | l -> l'  where@@ -162,23 +166,23 @@ {-----------------------------------------------------------------------------}  ----- A nicer notation for lists+-- * A nicer notation for lists -- --- List termination+-- | List termination hEnd :: HCons t t1 -> HCons t t1 hEnd t@(HCons _ _) = t -{-+{- ^    Note:-        - x :: HCons a b-            means: forall a b. x :: HCons a b-        - hEnd x-            means: exists a b. x :: HCons a b++        [@x :: HCons a b@] means: @forall a b. x :: HCons a b@++        [@hEnd x@] means: @exists a b. x :: HCons a b@ -}  --- Building non-empty lists+-- **  Building non-empty lists  hBuild   :: (HBuild' HNil a r) => a -> r hBuild x =  hBuild' HNil x@@ -197,28 +201,28 @@  where   hBuild' l x y = hBuild' (HCons x l) y -{-+{- $hbuild -HList> let x = hBuild True in hEnd x-HCons True HNil+> 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' 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> 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))+> 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+> HList> hEnd (hBuild (Key 42) (Name "Angus") Cow (Price 75.5)) == angus+> True  -}  {-----------------------------------------------------------------------------} --- A heterogeneous apply operator+-- * A heterogeneous apply operator  class Apply f a r | f a -> r where   apply :: f -> a -> r@@ -226,13 +230,13 @@                                         -- type-level computations only  --- Normal function application+-- | Normal function application  instance Apply (x -> y) x y where   apply f x = f x  --- Identity+-- | Identity  data Id = Id @@ -242,7 +246,7 @@  {-----------------------------------------------------------------------------} --- A heterogeneous fold for all types+-- * A heterogeneous fold for all types  class HList l => HFoldr f v l r | f v l -> r  where@@ -262,6 +266,8 @@  {-----------------------------------------------------------------------------} +-- * Map+ class HMap f l l' | f l -> l'  where   hMap :: f -> l -> l'@@ -280,7 +286,7 @@  {-----------------------------------------------------------------------------} --- Map a heterogeneous list to a homogeneous one+-- * Map a heterogeneous list to a homogeneous one  class HMapOut f r e  where@@ -300,9 +306,13 @@  {-----------------------------------------------------------------------------} --- A heterogenous version of mapM.--- mapM :: forall b m a. (Monad m) => (a -> m b) -> [a] -> m [b]+-- * A heterogenous version of mapM.+--+-- > mapM :: forall b m a. (Monad m) => (a -> m b) -> [a] -> m [b]+-- -- Likewise for mapM_.+--+-- See "Data.HList.HSequence" if the result list should also be heterogenous.  hMapM   :: (Monad m, HMapOut f l (m e)) => f -> l -> [m e] hMapM f =  hMapOut f@@ -321,11 +331,12 @@  {-----------------------------------------------------------------------------} --- A reconstruction of append+-- * A reconstruction of append  append' :: [a] -> [a] -> [a] append' l l' = foldr (:) l' l +-- | Alternative implementation of 'hAppend'. Demonstrates 'HFoldr' hAppend' :: (HFoldr ApplyHCons v l r) => l -> v -> r hAppend' l l' = hFoldr ApplyHCons l' l @@ -338,10 +349,11 @@  {-----------------------------------------------------------------------------} --- A heterogeneous map for all types+-- * A heterogeneous map for all types  data HMap' f = HMap' f +-- | Same as 'hMap' only a different implementation. hMap' :: (HFoldr (HMap' f) HNil l r) => f -> l -> r hMap' f = hFoldr (HMap' f) hNil @@ -355,7 +367,7 @@  {-----------------------------------------------------------------------------} --- A function for showing+-- * A function for showing  data HShow  = HShow data HSeq x = HSeq x@@ -374,7 +386,7 @@  {-----------------------------------------------------------------------------} --- Type-level equality for lists+-- * Type-level equality for lists  instance HEq HNil HNil HTrue instance HList l => HEq HNil (HCons e l) HFalse@@ -385,7 +397,7 @@  {-----------------------------------------------------------------------------} --- Staged equality for lists+-- * Staged equality for lists  instance HStagedEq HNil HNil  where@@ -426,21 +438,21 @@ {-----------------------------------------------------------------------------}  --- Ensure a list to contain HNats only+-- * Ensure a list to contain HNats only  class HList l => HNats l instance HNats HNil instance (HNat n, HNats ns) => HNats (HCons n ns)  --- Static set property based on HEq+-- * Static set property based on HEq  class HSet l instance HSet HNil instance (HMember e l HFalse, HSet l) => HSet (HCons e l)  --- Find an element in a set based on HEq+-- * Find an element in a set based on HEq class HNat n => HFind e l n | e l -> n  where   hFind :: e -> l -> n@@ -469,7 +481,7 @@   hFind' _ e l = hSucc (hFind e l)  --- Membership test+-- * Membership test  class HBool b => HMember e l b | e l -> b instance HMember e HNil HFalse@@ -480,7 +492,8 @@ hMember _ _ = undefined  --- Another type-level membership test+-- ** Another type-level membership test+-- -- Check to see if an element e occurs in a list l -- If not, return HNothing -- If the element does occur, return HJust l'@@ -499,7 +512,7 @@   --- Membership test based on type equality+-- ** Membership test based on type equality  class HBool b => HTMember e l b | e l -> b instance HTMember e HNil HFalse@@ -510,10 +523,11 @@ hTMember _ _ = undefined  --- Intersection based on HTMember+-- * Intersection based on HTMember  class HTIntersect l1 l2 l3 | l1 l2 -> l3  where+  -- | Like 'Data.List.intersect'   hTIntersect :: l1 -> l2 -> l3  instance HTIntersect HNil l HNil@@ -544,8 +558,9 @@   hTIntersectBool _ _ t l1 = hTIntersect t l1  --- Turn a heterogeneous list into a homogeneous one+-- * Turn a heterogeneous list into a homogeneous one +-- | Same as @hMapOut Id@ class HList2List l e  where   hList2List :: l -> [e]@@ -562,8 +577,10 @@  {-----------------------------------------------------------------------------} --- Turn list in a list of justs+-- * With 'HMaybe' +-- ** Turn list in a list of justs+ class ToHJust l l' | l -> l'  where   toHJust :: l -> l'@@ -579,7 +596,7 @@  {-----------------------------------------------------------------------------} --- Extract justs from list of maybes+-- ** Extract justs from list of maybes  class FromHJust l l' | l -> l'  where@@ -600,7 +617,7 @@  {-----------------------------------------------------------------------------} --- Annotated lists+-- * Annotated lists  data HAddTag t = HAddTag t data HRmTag    = HRmTag@@ -619,14 +636,16 @@   apply HRmTag (e,_) = e  --- Annotate list with a type-level Boolean+-- | Annotate list with a type-level Boolean hFlag :: (HMap (HAddTag HTrue) l l') => l -> l' hFlag l = hAddTag hTrue l   {-----------------------------------------------------------------------------} --- Splitting by HTrue and HFalse+-- * Splitting by HTrue and HFalse++-- | Analogus to @Data.List.partition snd@  class HSplit l l' l'' | l -> l' l''  where
Data/HList/HOccurs.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE EmptyDataDecls, MultiParamTypeClasses, FlexibleInstances,   FlexibleContexts, OverlappingInstances, UndecidableInstances #-} -{-+{- |    The HList library     (C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke@@ -9,7 +9,9 @@    Result-type-driven operations on typeful heterogeneous lists. -} -module Data.HList.HOccurs where+module Data.HList.HOccurs (+    module Data.HList.HOccurs,+    ) where  import Data.HList.FakePrelude import Data.HList.HListPrelude@@ -196,35 +198,28 @@  {-----------------------------------------------------------------------------} --- Illustration of typical test scenarios--{-+-- * Illustration of typical test scenarios+{- $example  Retrieve the Breed of an animal. -ghci-or-hugs> hOccurs myAnimal :: Breed-Cow+> ghci-or-hugs> hOccurs myAnimal :: Breed+> Cow --} -{-- Normal hOccurs requires specification of the result type even if the result type is determined by the fact that we are faced with a singleton list. -ghci-or-hugs> hOccurs (HCons 1 HNil)+> ghci-or-hugs> hOccurs (HCons 1 HNil)+>+> <interactive>:1:+>     No instance for (HOccurs e1 (HCons e HNil)) -<interactive>:1:-    No instance for (HOccurs e1 (HCons e HNil)) --}--{-- However, hOccurs can be elaborated as improved as follows: -ghci-or-hugs> hLookup (HCons 1 HNil)-1+> ghci-or-hugs> hLookup (HCons 1 HNil)+> 1  -} 
Data/HList/HTypeIndexed.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances,   UndecidableInstances, FlexibleContexts #-} -{-+{- |    The HList library     (C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke@@ -56,13 +56,13 @@  {-----------------------------------------------------------------------------} --- Map a type to a natural+-- | Map a type to a natural  class HNat n => HType2HNat e l n | e l -> n instance (TypeEq e' e b, HType2HNatCase b e l n)       =>  HType2HNat e (HCons e' l) n --- Helper class+-- | Helper class  class (HBool b, HNat n) => HType2HNatCase b e l n | b e l -> n instance HOccursNot e l => HType2HNatCase HTrue e l HZero@@ -73,7 +73,7 @@   --- Map types to naturals+-- | Map types to naturals  class HTypes2HNats ps l ns | ps l -> ns  where@@ -93,28 +93,28 @@  {-----------------------------------------------------------------------------} --- Define type-indexed delete in terms of the natural-based primitive+-- | Define type-indexed delete in terms of the natural-based primitive hDeleteAtProxy :: (HDeleteAtHNat n l l', HType2HNat e l n) => Proxy e -> l -> l' hDeleteAtProxy p l = hDeleteAtHNat (hType2HNat p l) l   {-----------------------------------------------------------------------------} --- Define type-indexed update in terms of the natural-based update+-- | Define type-indexed update in terms of the natural-based update hUpdateAtType :: (HUpdateAtHNat n e l l', HType2HNat e l n) => e -> l -> l' hUpdateAtType e l = hUpdateAtHNat (hType2HNat (toProxy e) l) e l   {-----------------------------------------------------------------------------} --- Projection based on proxies+-- | Projection based on proxies hProjectByProxies :: (HProjectByHNats ns l l', HTypes2HNats ps l ns) => ps -> l -> l' hProjectByProxies ps l = hProjectByHNats (hTypes2HNats ps l) l   {-----------------------------------------------------------------------------} --- Splitting based on proxies+-- | Splitting based on proxies hSplitByProxies :: (HMap (HAddTag HTrue) l l', HSplitByHNats' ns l' l'1 l'',                    HTypes2HNats ps l ns) =>                   ps -> l -> (l'1, l'')
Data/HList/HZip.hs view
@@ -4,7 +4,7 @@  import Data.HList.HListPrelude -{-+{- |    The HList library     (C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke@@ -14,16 +14,7 @@  {-----------------------------------------------------------------------------} --- Test for zippability--class HZippable x y-instance HZippable HNil HNil-instance HZippable l l' => HZippable (HCons e l) (HCons e' l')---{-----------------------------------------------------------------------------}---- Zip and unzip+-- | Zip and unzip  class HZip x y l | x y -> l, l -> x y  where@@ -33,6 +24,13 @@ {-  -- Zipping version I++-- | Test for zippability: equal length.++class HZippable x y+instance HZippable HNil HNil+instance HZippable l l' => HZippable (HCons e l) (HCons e' l')+ -- Somehow too polymorphic. -- Version II specialises for HNil and HCons. 
Data/HList/Label1.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, UndecidableInstances #-} -{-+{- |    The HList library     (C) 2004-2006, Oleg Kiselyov, Ralf Laemmel, Keean Schupke@@ -17,34 +17,34 @@ import Data.HList.Record (ShowLabel(..))  --- Labels are type-level naturals+-- | Labels are type-level naturals  newtype Label x = Label x deriving Show  --- Public constructors for labels+-- | Public constructors for labels  label :: HNat n => n -> Label n label =  Label  --- Construct the first label+-- | Construct the first label firstLabel :: Label HZero firstLabel = label hZero  --- Construct the next label+-- | Construct the next label nextLabel ::( HNat t) => Label t -> Label (HSucc t) nextLabel (Label n) = label (hSucc n)  --- Equality on labels+-- | Equality on labels  instance HEq n n' b       => HEq (Label n) (Label n') b  --- Show label+-- | Show label  instance Show n => ShowLabel (Label n)  where
Data/HList/Label2.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, UndecidableInstances, EmptyDataDecls #-} -{-+{- |    The HList library     (C) 2004-2006, Oleg Kiselyov, Ralf Laemmel, Keean Schupke@@ -15,11 +15,14 @@    and description. The namespace part helps avoid confusions between    labels from different Haskell modules. The description is    an arbitrary nullary type constructor.+    For the sake of printing, the namespace part and the description    are required to be the instance of Show. One must make sure that    the show functions does not examine the value, as descr is purely phantom.    Here's an example of the good Label description:-        data MyLabelDescr; instance Show MyLabelDescr where show _ = "descr"++   >     data MyLabelDescr; instance Show MyLabelDescr where show _ = "descr"+    which obviously can be automated with Template Haskell.     This model requires all labels in a record to inhabit the same namespace.@@ -31,29 +34,29 @@ import Data.HList.Record (ShowLabel(..))  --- Labels are type-level naturals+-- | Labels are type-level naturals  data Label x ns desc  -- labels are exclusively type-level entities  --- Construct the first label+-- | Construct the first label  firstLabel :: ns -> desc -> Label HZero ns desc firstLabel = undefined  --- Construct the next label+-- | Construct the next label nextLabel :: Label x ns desc -> desc' -> Label (HSucc x) ns desc' nextLabel = undefined  --- Equality on labels (descriptions are ignored)+-- | Equality on labels (descriptions are ignored)  instance HEq x x' b       => HEq (Label x ns desc1) (Label x' ns desc2) b  --- Show label+-- | Show label  instance (HNat x, Show desc) => ShowLabel (Label x ns desc) where   showLabel = show . getd
Data/HList/Label3.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, UndecidableInstances, EmptyDataDecls #-} -{-+{- |    The HList library     (C) 2004-2006, Oleg Kiselyov, Ralf Laemmel, Keean Schupke@@ -15,11 +15,14 @@    and description. The namespace part helps avoid confusions between    labels from different Haskell modules. The description is    an arbitrary nullary type constructor.+    For the sake of printing, the description is required to be the    instance of Show. One must make sure that the show functions does    not examine the value, as descr is purely phantom. Here's an    example of the good Label description:-        data MyLabelDescr; instance Show MyLabelDescr where show _ = "descr"++   >     data MyLabelDescr; instance Show MyLabelDescr where show _ = "descr"+    which obviously can be automated with Template Haskell.     This model even allows the labels in a record to belong to different@@ -33,23 +36,23 @@ import Data.HList.Record (ShowLabel(..))  --- Labels are type-level naturals+-- | Labels are type-level naturals data Label x ns desc  -- labels are exclusively type-level entities   -- Public constructors for labels --- Construct the first label+-- | Construct the first label firstLabel :: ns -> desc -> Label HZero ns desc firstLabel = undefined  --- Construct the next label+-- | Construct the next label nextLabel :: Label x ns desc -> desc' -> Label (HSucc x) ns desc' nextLabel = undefined  --- Equality on labels (descriptions are ignored)+-- | Equality on labels (descriptions are ignored)  instance ( HEq x x' b          , TypeEq ns ns' b'@@ -58,7 +61,7 @@       =>   HEq (Label x ns desc) (Label x' ns' desc') b''  --- Show label+-- | Show label  instance (HNat x, Show desc) => ShowLabel (Label x ns desc) where   showLabel = show . getd
Data/HList/Label4.hs view
@@ -1,11 +1,14 @@ {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, UndecidableInstances, EmptyDataDecls #-}-{-+{- |    The HList library     (C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke     Yet another model of labels.+    Labels are type proxies.++   See "Data.HList.MakeLabels" -}  module Data.HList.Label4 where@@ -17,12 +20,12 @@ import Data.HList.Record  --- Equality on labels+-- | Equality on labels  instance TypeEq x y b => HEq (Proxy x) (Proxy y) b  --- Show label+-- | Show label  instance Typeable x => ShowLabel (Proxy x)  where
Data/HList/Label5.hs view
@@ -1,13 +1,15 @@ {-# LANGUAGE FlexibleInstances, UndecidableInstances, MultiParamTypeClasses #-} -{-+{- |    The HList library     (C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke     Yet another model of labels.+    This model allow us to use any type as label type.    As a result, we need some generic instances.+    Also, type errors may be more confusing now. -} @@ -19,12 +21,12 @@ import Data.HList.Record  --- Equality on labels+-- | Equality on labels  instance TypeEq x y b => HEq x y b  --- Show label+-- | Show label  instance Typeable x => ShowLabel x  where
+ Data/HList/MakeLabels.hs view
@@ -0,0 +1,108 @@+{-# LANGUAGE TemplateHaskell, FlexibleInstances, EmptyDataDecls #-}+++{- | Making labels++ The following TH splice++>  $(makeLabels ["getX","getY","draw"])++should expand into the following declarations++> data GetX;     getX     = proxy::Proxy GetX+> data GetY;     getY     = proxy::Proxy GetY+> data Draw;     draw     = proxy::Proxy Draw++-}++module Data.HList.MakeLabels (makeLabels,label) where++import Data.HList.FakePrelude++import Language.Haskell.TH.Ppr (pprint)+import Language.Haskell.TH.Syntax++import Data.Char (toUpper, toLower)+import Control.Monad (liftM)++capitalize, uncapitalize :: String -> String+capitalize   (c:rest) = toUpper c : rest+uncapitalize (c:rest) = toLower c : rest+++-- Make the name of the type constructor whose string representation+-- is capitalized str+make_tname str = mkName $ capitalize str++-- Make the name of the value identifier whose string representation+-- is uncapitalized str+make_dname str = mkName $ uncapitalize str++-- The template of our declaration. We will then replace all occurences+-- of Foo with the desired name+dcl_template = [d| data Foo; foo = proxy::Proxy Foo |]++-- A very dirty traversal/replacement...++class ReplaceSyntax a where+    replace_name :: (Name,Name) -> (Name,Name) -> a -> a++instance ReplaceSyntax [Dec] where+    replace_name frm to dcls = map (replace_name frm to) dcls++instance ReplaceSyntax Dec where+    replace_name (tfrom,dfrom) (tto,dto)+                 dcl@(DataD ctx n parms con othern) =+                     if tfrom == n then+                        DataD ctx tto parms con othern+                        else dcl+    replace_name (tfrom,dfrom) (tto,dto)+                 dcl@(ValD (VarP n) (NormalB body) []) =+          let n' = if n == dfrom then dto else n+          in ValD (VarP n')+                  (NormalB (replace_name (tfrom,dfrom) (tto,dto) body)) []++    replace_name (tfrom,dfrom) (tto,dto) dcl =+        error $ "Can't handle: " ++ show dcl+++instance ReplaceSyntax Exp where+    replace_name from to (SigE exp tp) =+                     SigE (replace_name from to exp)+                          (replace_name from to tp)+    replace_name from to exp = exp+++instance ReplaceSyntax Type where+    replace_name (tfrom,dfrom) (tto,dto) tp@(ConT n) =+        if n == tfrom then (ConT tto) else tp+    replace_name from to (AppT t1 t2) =+        (AppT (replace_name from to t1) (replace_name from to t2))++-- | Our main function+makeLabels :: [String] -> Q [Dec]+makeLabels = liftM concat . sequence . map repl+ where+ repl n = liftM (replace_name from (to n)) dcl_template+ from = (make_tname "foo",make_dname "foo")+ to n = (make_tname n,make_dname n)++-- | Make a single label+label :: String -> Q [Dec]+label s = makeLabels [s]++-- Show the code expression+show_code cde = runQ cde >>= putStrLn . pprint++{-+t1 = show_code [d| data Foo |]++t2 = showName $ mkName "Foo"++t3 = show_code $+     liftM (replace_name+            (make_tname "foo",make_dname "foo")+            (make_tname "bar",make_dname "bar")) dcl_template+-}++t4 = show_code $ makeLabels ["getX","getY","draw"]
Data/HList/Record.hs view
@@ -2,7 +2,7 @@   FlexibleContexts, UndecidableInstances, ScopedTypeVariables #-} {-# OPTIONS_GHC -fno-warn-missing-signatures #-} -{-+{- |    The HList library     (C) 2004-2006, Oleg Kiselyov, Ralf Laemmel, Keean Schupke@@ -10,11 +10,104 @@    Extensible records     The are different models of labels that go with this module;-   see the files Label?.hs.+   see:++   * "Data.HList.Label1"++   * "Data.HList.Label2"++   * "Data.HList.Label3"++   * "Data.HList.Label4"++   * "Data.HList.Label5" -} -module Data.HList.Record where+module Data.HList.Record+(+    -- * Records +    -- ** Labels+    -- $labels+    LVPair(..),+    labelLVPair,+    newLVPair,++    -- ** Record+    Record(..),+    mkRecord,+    emptyRecord,++    -- *** Getting Labels+    RecordLabels,+    recordLabels,+    recordLabels',++    -- *** Getting Values+    RecordValues(..),+    recordValues,++    -- * Operations+    -- ** Show+    -- | A corresponding 'Show' instance exists as+    --+    -- > show x = "Record {" ++ showComponents "" x ++ "}"+    ShowComponents(..),+    ShowLabel(..),++    -- ** Lookup+    HasField(..),+    HasField'(..),++    -- ** Delete+    -- | 'hDeleteAtLabel' @label record@+    hDeleteAtLabel,++    -- ** Update+    -- | 'hUpdateAtLabel' @label value record@+    hUpdateAtLabel,+    hTPupdateAtLabel,++    -- ** Rename Label+    hRenameLabel,++    -- ** Projection+    -- $projection+    hProjectByLabels,+    hProjectByLabels2,++    -- ** Unions+    -- *** Left+    HLeftUnion(hLeftUnion),+    HLeftUnionBool(hLeftUnionBool),++    -- *** Symmetric+    -- $symmetricUnion+    UnionSymRec(unionSR),++    -- ** Reorder Labels+    hRearrange,++    -- ** Extension+    -- | 'hExtend', 'hAppend'++    -- * Unclassified+    -- | Probably internals, that may not be useful+    DuplicatedLabel(..),+    ExtraField(..),+    FieldNotFound(..),+    H2ProjectByLabels(h2projectByLabels),+    H2ProjectByLabels'(h2projectByLabels'),+    HLabelSet,+    HLabelSet',+    HRLabelSet,+    HRLabelSet',+    HRearrange(hRearrange2),+    HRearrange'(hRearrange2'),+    UnionSymRec'(..)+) where++ import Data.HList.FakePrelude import Data.HList.HListPrelude import Data.HList.HArray@@ -22,16 +115,16 @@  {-----------------------------------------------------------------------------} --- Record types as label-value pairs, where label is purely phantom.+-- $labels Record types as label-value pairs, where label is purely phantom. -- Thus the run-time representation of a field is the same as that of -- its value, and the record, at run-time, is indistinguishable from -- the HList of field values. At run-time, all information about the -- labels is erased. --- Field of label l with value type v+-- | Field of label l with value type v newtype LVPair l v = LVPair { valueLVPair :: v } deriving Eq --- Label accessor+-- | Label accessor labelLVPair :: LVPair l v -> l labelLVPair = undefined @@ -41,17 +134,17 @@ newtype Record r = Record r deriving Eq  --- Build a record+-- | Build a record mkRecord :: HRLabelSet r => r -> Record r mkRecord = Record  --- Build an empty record+-- | Build an empty record emptyRecord :: Record HNil emptyRecord = mkRecord HNil  --- Propery of a proper label set for a record: no duplication of labels+-- | Propery of a proper label set for a record: no duplication of labels  class HRLabelSet ps instance HRLabelSet HNil@@ -80,7 +173,8 @@ data DuplicatedLabel l = DuplicatedLabel l instance Fail (DuplicatedLabel x) => HLabelSet' x ls HTrue --- Construct the (phantom) list of labels of the record.+-- | Construct the (phantom) list of labels of the record.+-- -- This is a purely type-level function. class RecordLabels r ls | r -> ls instance RecordLabels HNil HNil@@ -93,7 +187,7 @@ recordLabels :: RecordLabels r ls => Record r -> ls recordLabels (Record r) = recordLabels' r --- Construct the list of values of the record.+-- | Construct the list of values of the record. class RecordValues r ls | r -> ls     where recordValues' :: r -> ls instance RecordValues HNil HNil@@ -109,7 +203,7 @@  {-----------------------------------------------------------------------------} --- A Show instance to appeal to normal records+-- 'Show' instance to appeal to normal records  instance ShowComponents r => Show (Record r)  where@@ -145,7 +239,7 @@  {-----------------------------------------------------------------------------} --- Extension for records+-- Extension  instance HRLabelSet (HCons (LVPair l v) r)     => HExtend (LVPair l v) (Record r) (Record (HCons (LVPair l v) r))@@ -155,7 +249,7 @@  {-----------------------------------------------------------------------------} --- Record concatenation+-- Concatenation  instance ( HRLabelSet r''          , HAppend r r' r''@@ -167,11 +261,15 @@  {-----------------------------------------------------------------------------} --- Lookup operation-+-- Lookup+--+-- | -- This is a baseline implementation. -- We use a helper class, HasField, to abstract from the implementation. +-- | Because 'hLookupByLabel' is so frequent and important, we implement+-- it separately, more efficiently. The algorithm is familiar assq, only+-- the comparison operation is done at compile-time class HasField l r v | l r -> v   where     hLookupByLabel:: l -> r -> v@@ -191,9 +289,6 @@ -}  --- Because hLookupByLabel is so frequent and important, we implement--- it separately, more efficiently. The algorithm is familiar assq, only--- the comparison operation is done at compile-time  instance HasField l r v => HasField l (Record r) v where     hLookupByLabel l (Record r) = hLookupByLabel l r@@ -215,7 +310,9 @@  {-----------------------------------------------------------------------------} --- Delete operation+-- Delete++hDeleteAtLabel :: (H2ProjectByLabels (HCons e HNil) t t1 t2) =>e -> Record t -> Record t2 hDeleteAtLabel l (Record r) = Record r'  where   (_,r')  = h2projectByLabels (HCons l HNil) r@@ -223,7 +320,9 @@  {-----------------------------------------------------------------------------} --- Update operation+-- Update++hUpdateAtLabel :: (HUpdateAtHNat n (LVPair l v) t l',HFind l ls n,RecordLabels t ls) =>l -> v -> Record t -> Record l' hUpdateAtLabel l v (Record r) = Record r'  where   n    = hFind l (recordLabels' r)@@ -231,17 +330,27 @@   {-----------------------------------------------------------------------------}--- Projection for records+-- Projection++-- $projection -- It is also an important operation: the basis of many -- deconstructors -- so we try to implement it efficiently.+++-- | @hProjectByLabels ls r@ returns @r@ with only the labels in @ls@ remaining hProjectByLabels :: (HRLabelSet a, H2ProjectByLabels ls t a b) => ls -> Record t -> Record a hProjectByLabels ls (Record r) = mkRecord (fst $ h2projectByLabels ls r) +-- | See 'H2ProjectByLabels'+hProjectByLabels2 :: (H2ProjectByLabels ls t t1 t2, HRLabelSet t1, HRLabelSet t2) =>ls -> Record t -> (Record t1, Record t2) hProjectByLabels2 ls (Record r) = (mkRecord rin, mkRecord rout)    where (rin,rout) = h2projectByLabels ls r --- Invariant: r = rin `disjoint-union` rout---            labels(rin) = ls+-- | /Invariant/:+--+--  > r === rin `disjoint-union` rout+--  > labels rin === ls+--  >     where (rin,rout) = hProjectByLabels ls r class H2ProjectByLabels ls r rin rout | ls r -> rin rout where     h2projectByLabels :: ls -> r -> (rin,rout) @@ -275,7 +384,9 @@  {-----------------------------------------------------------------------------} --- Rename the label of record+-- | Rename the label of record+hRenameLabel :: (HRLabelSet (HCons (LVPair l v) t2),HasField e t1 v,H2ProjectByLabels (HCons e HNil) t1 t t2) =>+    e -> l -> Record t1 -> Record (HCons (LVPair l v) t2) hRenameLabel l l' r = r''  where   v   = hLookupByLabel l r@@ -285,28 +396,29 @@  {-----------------------------------------------------------------------------} --- A variation on update: type-preserving update.+-- | A variation on 'hUpdateAtLabel': type-preserving update.+hTPupdateAtLabel :: (HasField l t a,HUpdateAtHNat n (LVPair l a) t l',HFind l ls n,RecordLabels t ls) =>+    l -> a -> Record t -> Record l' hTPupdateAtLabel l v r = hUpdateAtLabel l v r  where    te :: a -> a -> ()    te _ _ = ()    _ = te v (hLookupByLabel l r) -{-+{- ^ --- We could also say:+We could also say: -hTPupdateAtLabel l v r = hUpdateAtLabel l v r `asTypeOf` r+> hTPupdateAtLabel l v r = hUpdateAtLabel l v r `asTypeOf` r --- Then we were taking a dependency on Haskell's type equivalence.--- This would also constrain the actual implementation of hUpdateAtLabel.+Then we were taking a dependency on Haskell's type equivalence.+This would also constrain the actual implementation of hUpdateAtLabel.  -}  {-----------------------------------------------------------------------------} --- Subtyping for records-+-- | Subtyping for records instance ( RecordLabels r' ls          , H2ProjectByLabels ls r r' rout          )@@ -315,6 +427,8 @@  {-----------------------------------------------------------------------------} +-- Left Union+ class  HLeftUnion r r' r'' | r r' -> r''  where hLeftUnion :: r -> r' -> r'' @@ -345,23 +459,30 @@   {-----------------------------------------------------------------------------}+-- $symmetricUnion -- Compute the symmetric union of two records r1 and r2 and -- return the pair of records injected into the union (ru1, ru2).--- To be more precise, we compute the symmetric union _type_ ru--- of two record _types_ r1 and r2. The emphasis on types is important.--- The two records (ru1,ru2) in the result of unionSR have the same+--+-- To be more precise, we compute the symmetric union /type/ @ru@+-- of two record /types/ @r1@ and @r2@. The emphasis on types is important.+--+-- The two records (ru1,ru2) in the result of 'unionSR' have the same -- type ru, but they are generally different values. -- Here the simple example: suppose---   r1 = (Label .=. True)  .*. emptyRecord---   r2 = (Label .=. False) .*. emptyRecord--- Then unionSR r1 r2 will return (r1,r2). Both components of the result+--+-- >  r1 = (Label .=. True)  .*. emptyRecord+-- >  r2 = (Label .=. False) .*. emptyRecord+--+-- Then 'unionSR' r1 r2 will return (r1,r2). Both components of the result -- are different records of the same type.---- To project from the union ru, use hProjectByLabels.+--+--+-- To project from the union ru, use 'hProjectByLabels'. -- It is possible to project from the union obtaining a record -- that was not used at all when creating the union.--- We do assure however that if (unionSR r1 r2) gave (r1u,r2u),--- then projecting r1u onto the type of r1 gives the _value_ identical+--+-- We do assure however that if @unionSR r1 r2@ gave @(r1u,r2u)@,+-- then projecting r1u onto the type of r1 gives the /value/ identical -- to r1. Ditto for r2.  class UnionSymRec r1 r2 ru | r1 r2 -> ru where@@ -382,8 +503,9 @@ class UnionSymRec' b r1 f2 r2' ru | b r1 f2 r2' -> ru where     unionSR' :: b -> r1 -> f2 -> r2'  -> (ru, ru) --- Field f2 is already in r1, so it will be in the union of r1+-- | Field f2 is already in r1, so it will be in the union of r1 -- with the rest of r2.+-- -- To inject (HCons f2 r2) in that union, we should replace the -- field f2 instance (UnionSymRec r1 r2' (Record ru),@@ -406,13 +528,13 @@              ur' = hExtend f2 ur  {-----------------------------------------------------------------------------}--- Rearranges a record by labels. Returns the record r, rearranged such that+-- | Rearranges a record by labels. Returns the record r, rearranged such that -- the labels are in the order given by ls. (recordLabels r) must be a -- permutation of ls. hRearrange :: (HLabelSet ls, HRearrange ls r r') => ls -> Record r -> Record r' hRearrange ls (Record r) = Record $ hRearrange2 ls r --- Helper class for hRearrange+-- | Helper class for 'hRearrange' class HRearrange ls r r' | ls r -> r' where     hRearrange2 :: ls -> r -> r' @@ -425,7 +547,7 @@    hRearrange2 ~(HCons l ls) r = hRearrange2' l ls rin rout       where (rin, rout) = h2projectByLabels (HCons l HNil) r --- Helper class 2 for hRearrange+-- | Helper class 2 for 'hRearrange' class HRearrange' l ls rin rout r' | l ls rin rout -> r' where     hRearrange2' :: l -> ls -> rin -> rout -> r' instance HRearrange ls rout r' =>@@ -435,9 +557,12 @@ data ExtraField l = ExtraField data FieldNotFound l = FieldNotFound +-- | For improved error messages instance Fail (FieldNotFound l) =>          HRearrange' l ls HNil rout (FieldNotFound l) where    hRearrange2' _ _ _ _ = FieldNotFound++-- | For improved error messages instance Fail (ExtraField l) =>            HRearrange HNil (HCons (LVPair l v) a) (ExtraField l) where    hRearrange2 _ _ = ExtraField
Data/HList/RecordP.hs view
@@ -2,13 +2,14 @@   UndecidableInstances, FlexibleInstances #-} {-# OPTIONS -fglasgow-exts #-} -{-+{- |    The HList library     (C) 2004-2006, Oleg Kiselyov, Ralf Laemmel, Keean Schupke     Extensible records: labels are phantom, so at run-time, the record    is just a heterogenous list of field values.+    This sort of record is generalizable to `tables' (which are, at    run-time, a list or a map containing the heterogenous lists    of field values).
Data/HList/TIC.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE FlexibleInstances, FlexibleContexts #-} -{-+{- |    The HList library     (C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke@@ -20,14 +20,14 @@  {-----------------------------------------------------------------------------} --- A datatype for type-indexed co-products+-- | A datatype for type-indexed co-products  data TIC l = TIC Dynamic   {-----------------------------------------------------------------------------} --- Public constructor+-- | Public constructor  mkTIC :: ( HTypeIndexed l          , HTypeProxied l@@ -41,7 +41,7 @@  {-----------------------------------------------------------------------------} --- Public destructor+-- | Public destructor  unTIC :: ( HTypeIndexed l          , HTypeProxied l@@ -55,7 +55,7 @@  {-----------------------------------------------------------------------------} --- A type-indexed type sequence that is a sequence of proxy types+-- | A type-indexed type sequence that is a sequence of proxy types  class HTypeProxied l instance HTypeProxied HNil@@ -64,7 +64,7 @@  {-----------------------------------------------------------------------------} --- TICs are opaque+-- | TICs are opaque  instance Show (TIC l)  where
Data/HList/TIP.hs view
@@ -2,9 +2,7 @@ {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, UndecidableInstances,     FlexibleContexts #-} -module Data.HList.TIP where--{-+{- |    The HList library     (C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke@@ -12,6 +10,9 @@    Type-indexed products. -} +module Data.HList.TIP where++ import Data.HList.FakePrelude import Data.HList.HListPrelude import Data.HList.HArray@@ -21,7 +22,7 @@  {-----------------------------------------------------------------------------} --- The newtype for type-indexed products+-- | The newtype for type-indexed products  newtype TIP l = TIP l         deriving (Read,Show)@@ -39,7 +40,7 @@  {-----------------------------------------------------------------------------} --- Type-indexed type sequences+-- | Type-indexed type sequences  class HList l => HTypeIndexed l instance HTypeIndexed HNil@@ -75,12 +76,14 @@  {-----------------------------------------------------------------------------} --- Type-indexed extension+-- | Type-indexed extension+-- -- signature is inferred--- hExtend' :: (HTypeIndexed t, HOccursNot e t) => e -> TIP t -> TIP (HCons e t)+--+-- > hExtend' :: (HTypeIndexed t, HOccursNot e t) => e -> TIP t -> TIP (HCons e t) hExtend' e (TIP l) = mkTIP (HCons e l) -{-+{- $example  Valid type I @@ -148,7 +151,7 @@  {-----------------------------------------------------------------------------} --- Shielding type-indexed operations+-- | Shielding type-indexed operations -- The absence of signatures is deliberate! They all must be inferred.  onTIP f (TIP l) = mkTIP (f l)@@ -175,56 +178,60 @@  {-----------------------------------------------------------------------------} --- Sample code+-- * Sample code -{-+{- $sampleCode  Assume -myTipyCow = TIP myAnimal+> myTipyCow = TIP myAnimal -animalKey :: (HOccurs Key l, SubType l (TIP Animal)) => l -> Key-animalKey = hOccurs+> animalKey :: (HOccurs Key l, SubType l (TIP Animal)) => l -> Key+> animalKey = hOccurs  Session log -*TIP> :t myTipyCow-myTipyCow :: TIP Animal+> *TIP> :t myTipyCow+> myTipyCow :: TIP Animal -*TIP> hOccurs myTipyCow :: Breed-Cow+> *TIP> hOccurs myTipyCow :: Breed+> Cow -*TIP> hExtend BSE myTipyCow-TIP (HCons BSE-    (HCons (Key 42)-    (HCons (Name "Angus")-    (HCons Cow-    (HCons (Price 75.5)-     HNil)))))+> *TIP> hExtend BSE myTipyCow+> TIP (HCons BSE+>     (HCons (Key 42)+>     (HCons (Name "Angus")+>     (HCons Cow+>     (HCons (Price 75.5)+>      HNil))))) -*TIP> BSE .*. myTipyCow---- same as before ---+> *TIP> BSE .*. myTipyCow+> --- same as before --- -*TIP> Sheep .*. myTipyCow-Type error ...+> *TIP> Sheep .*. myTipyCow+> Type error ... -*TIP> Sheep .*. tipyDelete myTipyCow (HProxy::HProxy Breed)-TIP (HCons Sheep (HCons (Key 42) (HCons (Name "Angus") (HCons (Price 75.5) HNil))))+> *TIP> Sheep .*. tipyDelete myTipyCow (HProxy::HProxy Breed)+>TIP (HCons Sheep (HCons (Key 42) (HCons (Name "Angus") (HCons (Price 75.5) HNil)))) -*TIP> tipyUpdate myTipyCow Sheep-TIP (HCons (Key 42) (HCons (Name "Angus") (HCons Sheep (HCons (Price 75.5) HNil))))+> *TIP> tipyUpdate myTipyCow Sheep+> TIP (HCons (Key 42) (HCons (Name "Angus") (HCons Sheep (HCons (Price 75.5) HNil))))  -}  {-----------------------------------------------------------------------------} +-- * Sample 2++-- | -- This example from the TIR paper challenges singleton lists. -- Thanks to the HW 2004 reviewer who pointed out the value of this example. -- We note that the explicit type below is richer than the inferred type. -- This richer type is needed for making this operation more polymorphic.--- That is, a) would not work without the explicit type, while it would:---  a)  ((+) (1::Int)) $ snd $ tuple oneTrue---  b)  ((+) (1::Int)) $ fst $ tuple oneTrue+-- That is, /a)/ would not work without the explicit type, while it would:+--+-- >  a)  ((+) (1::Int)) $ snd $ tuple oneTrue+-- >  b)  ((+) (1::Int)) $ fst $ tuple oneTrue  tuple :: ( HOccurs e1 (TIP l)          , HType2HNat e1 l n@@ -244,7 +251,7 @@                 in (x,y)  --- A specific tuple+-- | A specific tuple oneTrue :: TIP (HCons Int (HCons Bool HNil)) oneTrue = hExtend (1::Int) (hExtend True emptyTIP) 
Data/HList/TypeCastGeneric1.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} -{-+{- |    The HList library     (C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke
Data/HList/TypeCastGeneric2.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, FunctionalDependencies, UndecidableInstances #-}-{-+{- |    The HList library     (C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke@@ -7,7 +7,8 @@    A generic implementation of a type-safe cast. The specific coding    here is only shown for completeness' sake and it is explained in the    TR version of the paper. The shown coding does not rely on separate-   compilation (while TypeCastGeneric1.hs does), but on some other tricks.+   compilation (while "Data.HList.TypeCastGeneric1" does), but on some other+   tricks. -}  module Data.HList.TypeCastGeneric2 where
Data/HList/TypeEqBoolGeneric.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, FlexibleContexts #-}-{-+{- |    The HList library     (C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke
Data/HList/TypeEqGeneric1.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances,   FlexibleContexts, OverlappingInstances, UndecidableInstances #-}-{-+{- |    The HList library     (C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke@@ -15,7 +15,7 @@    and by transitive closure therefore relies on separate compilation    of TypeCast clients and the TypeCast instance. -   There is another encoding in TypeEqGeneric2.hs.+   There is another encoding in "Data.Hlist.TypeEqGeneric2". -}  module Data.HList.TypeEqGeneric1 where
Data/HList/TypeEqGeneric2.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleContexts, FlexibleInstances, UndecidableInstances, OverlappingInstances #-} -{-+{- |    The HList library     (C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke@@ -8,7 +8,7 @@    A generic implementation of a type equality predicate. The given    implementation only works for GHC. The specific coding here is only    shown for completeness' sake. We actually favour the encoding from-   TypeEqGeneric1.hs for its conciseness. The specific coding here+   "Data.Hlist.TypeEqGeneric1" for its conciseness. The specific coding here    does not rely on separate compilation (while TypeEqGeneric1.hs    does), but on some other tricks. -}
Data/HList/Variant.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances,   UndecidableInstances, FlexibleContexts #-} -{-+{- |    The HList library     (C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke@@ -29,14 +29,14 @@  {-----------------------------------------------------------------------------} --- Variant types on the basis of label-maybe pairs.+-- | Variant types on the basis of label-maybe pairs.  newtype Variant mr = Variant mr   {-----------------------------------------------------------------------------} --- Turn proxy sequence into sequence of Nothings+-- | Turn proxy sequence into sequence of Nothings  class HMaybied r r' | r -> r'  where@@ -54,7 +54,7 @@  {-----------------------------------------------------------------------------} --- Public constructor+-- | Public constructor  mkVariant :: ( RecordLabels v ls              , HFind x ls n@@ -72,7 +72,7 @@  {-----------------------------------------------------------------------------} --- Public destructor+-- | Public destructor  unVariant :: ( RecordLabels v ls              , HFind x ls n@@ -88,7 +88,7 @@  {-----------------------------------------------------------------------------} --- Variants are opaque+-- | Variants are opaque  instance Show (Variant v)  where
HList.cabal view
@@ -1,5 +1,5 @@ Name:                HList-Version:             0.2.1+Version:             0.2.2 Category:            Data Synopsis:            Heterogeneous lists Description:         HList is a record system providing strongly typed heterogenous lists, records,@@ -13,7 +13,7 @@ Data-files:          README Cabal-version:       >= 1.4 Tested-With:         GHC==6.8.2-Build-Depends:       base >= 3 && < 5+Build-Depends:       base >= 3 && < 5, template-haskell Build-Type:          Simple Exposed-modules:     Data.HList, Data.HList.CommonMain, Data.HList.Variant, Data.HList.GhcSyntax,                      Data.HList.GhcRecord, Data.HList.Record, Data.HList.HZip, Data.HList.TIC, Data.HList.TIP,@@ -21,7 +21,9 @@                      Data.HList.HListPrelude, Data.HList.TypeEqBoolGeneric, Data.HList.TypeEqGeneric1,                      Data.HList.TypeCastGeneric1, Data.HList.TypeCastGeneric2, Data.HList.FakePrelude,                       Data.HList.RecordP, Data.HList.TypeEqGeneric2,-                     Data.HList.Label1, Data.HList.Label2, Data.HList.Label3, Data.HList.Label4, Data.HList.Label5+                     Data.HList.Label1, Data.HList.Label2, Data.HList.Label3, Data.HList.Label4, Data.HList.Label5,++                     Data.HList.MakeLabels  extensions:          EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies,                      MultiParamTypeClasses, OverlappingInstances, ScopedTypeVariables, RankNTypes,
README view
@@ -1,21 +1,26 @@ (C) 2004--2010, Oleg Kiselyov, Ralf Laemmel, Keean Schupke +Contributors:+	Justin Bailey, Brian Bloniarz, Gwern Branwen, Einar Karttunen,+	and Adam Vogt++ The HList library and samples  ----------------------------------------------------------------------  Getting the code -> darcs get http://darcs.haskell.org/HList+> darcs get http://code.haskell.org/HList  ----------------------------------------------------------------------  Pushing changes -You need an account at darcs.haskell.org+You need an account at code.haskell.org  > cd HList-> darcs pull user@darcs.haskell.org:/srv/darcs/HList+> darcs pull user@code.haskell.org:/srv/darcs/HList > darcs record > darcs push @@ -29,11 +34,12 @@  You can get HList from Hackage or from Darcs: -$ darcs get --partial http://darcs.haskell.org/HList/+$ darcs get --partial http://code.haskell.org/HList/  The code works --- within the limits exercised in the source files --- for both GHC (6.4) and Hugs (Nov 2003). See the  examples/Makefile for ways of running test cases.+The last GHC version tried: GHC 6.12  One may run "cd examples; make test" to check the distribution.