Add documentation for Template Haskell functions
authorSimon Peyton Jones <simonpj@microsoft.com>
Mon, 16 Jul 2012 16:42:49 +0000 (17:42 +0100)
committerSimon Peyton Jones <simonpj@microsoft.com>
Mon, 16 Jul 2012 16:42:49 +0000 (17:42 +0100)
Thanks to Reiner Pope for doing this

Language/Haskell/TH/Syntax.hs

index d9c1dcc..8e18c52 100644 (file)
@@ -148,6 +148,17 @@ counter = unsafePerformIO (newIORef 0)
 
 newtype Q a = Q { unQ :: forall m. Quasi m => m a }
 
+-- \"Runs\" the 'Q' monad. Normal users of Template Haskell
+-- should not need this function, as the splice brackets @$( ... )@
+-- are the usual way of running a 'Q' computation.
+--
+-- This function is primarily used in GHC internals, and for debugging
+-- splices by running them in 'IO'. 
+--
+-- Note that many functions in 'Q', such as 'reify' and other compiler
+-- queries, are not supported when running 'Q' in 'IO'; these operations
+-- simply fail at runtime. Indeed, the only operations guaranteed to succeed
+-- are 'newName', 'runIO', 'reportError' and 'reportWarning'.
 runQ :: Quasi m => Q a -> m a
 runQ (Q m) = m
 
@@ -166,14 +177,52 @@ instance Applicative Q where
 
 ----------------------------------------------------
 -- Packaged versions for the programmer, hiding the Quasi-ness
+
+{- | 
+Generate a fresh name, which cannot be captured. 
+
+For example, this:
+
+@f = $(do
+  nm1 <- newName \"x\"
+  let nm2 = 'mkName' \"x\"
+  return ('LamE' ['VarP' nm1] (LamE [VarP nm2] ('VarE' nm1)))
+ )@
+
+will produce the splice
+
+>f = \x0 -> \x -> x0
+
+In particular, the occurrence @VarE nm1@ refers to the binding @VarP nm1@,
+and is not captured by the binding @VarP nm2@.
+
+Although names generated by @newName@ cannot /be captured/, they can
+/capture/ other names. For example, this:
+
+>g = $(do
+>  nm1 <- newName "x"
+>  let nm2 = mkName "x"
+>  return (LamE [VarP nm2] (LamE [VarP nm1] (VarE nm2)))
+> )
+
+will produce the splice
+
+>g = \x -> \x0 -> x0
+
+since the occurrence @VarE nm2@ is captured by the innermost binding
+of @x@, namely @VarP nm1@.
+-}
 newName :: String -> Q Name
 newName s = Q (qNewName s)
 
+-- | Report an error (True) or warning (False), 
+-- but carry on; use 'fail' to stop.
 report  :: Bool -> String -> Q ()
 report b s = Q (qReport b s)
 
-recover :: Q a -- ^ recover with this one
-        -> Q a -- ^ failing action
+-- | Recover from errors raised by 'reportError' or 'fail'.
+recover :: Q a -- ^ handler to invoke on failure
+        -> Q a -- ^ computation to run
         -> Q a
 recover (Q r) (Q m) = Q (qRecover r m)
 
@@ -182,24 +231,100 @@ recover (Q r) (Q m) = Q (qRecover r m)
 lookupName :: Bool -> String -> Q (Maybe Name)
 lookupName ns s = Q (qLookupName ns s)
 
-lookupTypeName, lookupValueName :: String -> Q (Maybe Name)
+-- | Look up the given name in the (type namespace of the) current splice's scope. See "Language.Haskell.TH.Syntax#namelookup" for more details.
+lookupTypeName :: String -> Q (Maybe Name)
 lookupTypeName  s = Q (qLookupName True s)
+
+-- | Look up the given name in the (value namespace of the) current splice's scope. See "Language.Haskell.TH.Syntax#namelookup" for more details.
+lookupValueName :: String -> Q (Maybe Name)
 lookupValueName s = Q (qLookupName False s)
 
--- | 'reify' looks up information about the 'Name'
+{-
+Note [Name lookup]
+~~~~~~~~~~~~~~~~~~
+-}
+{- $namelookup #namelookup#
+The functions 'lookupTypeName' and 'lookupValueName' provide
+a way to query the current splice's context for what names
+are in scope. The function 'lookupTypeName' queries the type
+namespace, whereas 'lookupValueName' queries the value namespace,
+but the functions are otherwise identical.
+
+A call @lookupValueName s@ will check if there is a value
+with name @s@ in scope at the current splice's location. If
+there is, the @Name@ of this value is returned;
+if not, then @Nothing@ is returned.
+
+The returned name cannot be \"captured\". 
+For example:
+
+> f = "global"
+> g = $( do
+>          Just nm <- lookupValueName "f"
+>          [| let f = "local" in $( varE nm ) |]
+
+In this case, @g = \"global\"@; the call to @lookupValueName@
+returned the global @f@, and this name was /not/ captured by
+the local definition of @f@.
+
+The lookup is performed in the context of the /top-level/ splice
+being run. For example:
+
+> f = "global"
+> g = $( [| let f = "local" in 
+>            $(do
+>                Just nm <- lookupValueName "f"
+>                varE nm
+>             ) |] )
+
+Again in this example, @g = \"global\"@, because the call to
+@lookupValueName@ queries the context of the outer-most @$(...)@.
+
+Operators should be queried without any surrounding parentheses, like so:
+
+> lookupValueName "+"
+
+Qualified names are also supported, like so:
+
+> lookupValueName "Prelude.+"
+> lookupValueName "Prelude.map"
+
+-}
+
+
+{- | 'reify' looks up information about the 'Name'.
+
+It is sometimes useful to construct the argument name using 'lookupTypeName' or 'lookupValueName'
+to ensure that we are reifying from the right namespace. For instance, in this context:
+
+> data D = D
+
+which @D@ does @reify (mkName \"D\")@ return information about? (Answer: @D@-the-type, but don't rely on it.)
+To ensure we get information about @D@-the-value, use 'lookupValueName':
+
+> do
+>   Just nm <- lookupValueName "D"
+>   reify nm
+
+and to get information about @D@-the-type, use 'lookupTypeName'.
+-}
 reify :: Name -> Q Info
 reify v = Q (qReify v)
 
--- | 'classInstances' looks up instaces of a class
-reifyInstances :: Name -> [Type] -> Q [Dec]
+{- | @reifyInstances nm tys@ returns a list of visible instances of @nm tys@. That is, 
+if @nm@ is the name of a type class, then all instances of this class at the types @tys@
+are returned. Alternatively, if @nm@ is the name of a data family or type family,
+all instances of this family at the types @tys@ are returned.
+-}
+reifyInstances :: Name -> [Type] -> Q [InstanceDec]
 reifyInstances cls tys = Q (qReifyInstances cls tys)
 
+-- | Is the list of instances returned by 'reifyInstances' nonempty?
 isInstance :: Name -> [Type] -> Q Bool
 isInstance nm tys = do { decs <- reifyInstances nm tys
                        ; return (not (null decs)) }
 
--- | 'location' gives you the 'Location' at which this
--- computation is spliced.
+-- | The location at which this computation is spliced.
 location :: Q Loc
 location = Q qLocation
 
@@ -364,8 +489,7 @@ occString (OccName occ) = occ
 -----------------------------------------------------
 --              Names
 -----------------------------------------------------
-
--- |
+-- 
 -- For "global" names ('NameG') we need a totally unique name,
 -- so we must include the name-space of the thing
 --
@@ -389,6 +513,63 @@ occString (OccName occ) = occ
 -- The 'map' will be a NameG, and 'x' wil be a NameL
 --
 -- These Names should never appear in a binding position in a TH syntax tree
+
+{- $namecapture #namecapture#
+Much of 'Name' API is concerned with the problem of /name capture/, which
+can be seen in the following example.
+
+> f expr = [| let x = 0 in $expr |]
+> ...
+> g x = $( f [| x |] )
+> h y = $( f [| y |] )
+
+A naive desugaring of this would yield:
+
+> g x = let x = 0 in x
+> h y = let x = 0 in y
+
+All of a sudden, @g@ and @h@ have different meanings! In this case,
+we say that the @x@ in the RHS of @g@ has been /captured/
+by the binding of @x@ in @f@.
+
+What we actually want is for the @x@ in @f@ to be distinct from the
+@x@ in @g@, so we get the following desugaring:
+
+> g x = let x' = 0 in x
+> h y = let x' = 0 in y
+
+which avoids name capture as desired. 
+
+In the general case, we say that a @Name@ can be captured if
+the thing it refers to can be changed by adding new declarations.
+-}
+
+{- |
+An abstract type representing names in the syntax tree.
+
+'Name's can be constructed in several ways, which come with different
+name-capture guarantees (see "Language.Haskell.TH.Syntax#namecapture" for
+an explanation of name capture):
+
+  * the built-in syntax @'f@ and @''T@ can be used to construct names, 
+    The expression @'f@ gives a @Name@ which refers to the value @f@ 
+    currently in scope, and @''T@ gives a @Name@ which refers to the
+    type @T@ currently in scope. These names can never be captured.
+    
+  * 'lookupValueName' and 'lookupTypeName' are similar to @'f@ and 
+     @''T@ respectively, but the @Name@s are looked up at the point
+     where the current splice is being run. These names can never be
+     captured.
+
+  * 'newName' monadically generates a new name, which can never
+     be captured.
+     
+  * 'mkName' generates a capturable name.
+
+Names constructed using @newName@ and @mkName@ may be used in bindings
+(such as @let x = ...@ or @\x -> ...@), but names constructed using
+@lookupValueName@, @lookupTypeName@, @'f@, @''T@ may not.
+-}
 data Name = Name OccName NameFlavour deriving (Typeable, Data)
 
 data NameFlavour
@@ -453,17 +634,42 @@ data NameSpace = VarName  -- ^ Variables
 
 type Uniq = Int
 
--- | Base, unqualified name.
+-- | The name without its module prefix
 nameBase :: Name -> String
 nameBase (Name occ _) = occString occ
 
+-- | Module prefix of a name, if it exists
 nameModule :: Name -> Maybe String
 nameModule (Name _ (NameQ m))     = Just (modString m)
 nameModule (Name _ (NameG _ _ m)) = Just (modString m)
 nameModule _                      = Nothing
 
+{- | 
+Generate a capturable name. Occurrences of such names will be
+resolved according to the Haskell scoping rules at the occurrence
+site.
+
+For example:
+
+> f = [| pi + $(varE (mkName "pi")) |]
+> ...
+> g = let pi = 3 in $f
+
+In this case, @g@ is desugared to
+
+> g = Prelude.pi + 3
+
+Note that @mkName@ may be used with qualified names:
+
+> mkName "Prelude.pi"
+
+See also 'Language.Haskell.TH.Lib.dyn' for a useful combinator. The above example could
+be rewritten using 'dyn' as
+
+> f = [| pi + $(dyn "pi") |]
+-}
 mkName :: String -> Name
--- The string can have a '.', thus "Foo.baz",
+-- The string can have a '.', thus "Foo.baz",
 -- giving a dynamically-bound qualified name,
 -- in which case we want to generate a NameQ
 --
@@ -590,8 +796,10 @@ instance Show Name where
   show = showName
 
 -- Tuple data and type constructors
-tupleDataName :: Int -> Name    -- ^ Data constructor
-tupleTypeName :: Int -> Name    -- ^ Type constructor
+-- | Tuple data constructor
+tupleDataName :: Int -> Name
+-- | Tuple type constructor
+tupleTypeName :: Int -> Name
 
 tupleDataName 0 = mk_tup_name 0 DataName
 tupleDataName 1 = error "tupleDataName 1"
@@ -609,8 +817,10 @@ mk_tup_name n_commas space
     tup_mod = mkModName "GHC.Tuple"
 
 -- Unboxed tuple data and type constructors
-unboxedTupleDataName :: Int -> Name    -- ^ Data constructor
-unboxedTupleTypeName :: Int -> Name    -- ^ Type constructor
+-- | Unboxed tuple data constructor
+unboxedTupleDataName :: Int -> Name
+-- | Unboxed tuple type constructor
+unboxedTupleTypeName :: Int -> Name
 
 unboxedTupleDataName 0 = error "unboxedTupleDataName 0"
 unboxedTupleDataName 1 = error "unboxedTupleDataName 1"
@@ -640,7 +850,7 @@ data Loc
        , loc_start    :: CharPos
        , loc_end      :: CharPos }
 
-type CharPos = (Int, Int)      -- Line and character position
+type CharPos = (Int, Int)      -- Line and character position
 
 
 -----------------------------------------------------
@@ -651,55 +861,88 @@ type CharPos = (Int, Int) -- Line and character position
 
 -- | Obtained from 'reify' in the 'Q' Monad.
 data Info
-  = -- | A class is reified to its declaration 
-    --   and a list of its instances
-    ClassI 
-        Dec             -- Declaration of the class
-        [InstanceDec]  -- The instances of that class
-
+  = 
+  -- | A class, with a list of its visible instances
+  ClassI 
+      Dec
+      [InstanceDec]
+  
+  -- | A class method
   | ClassOpI
-       Name    -- The class op itself
-       Type    -- Type of the class-op (fully polymoprhic)
-       Name    -- Name of the parent class
-       Fixity
-
+       Name
+       Type
+       ParentName
+       Fixity
+  
+  -- | A \"plain\" type constructor. \"Fancier\" type constructors are returned using 'PrimTyConI' or 'FamilyI' as appropriate
   | TyConI 
         Dec
 
-  | FamilyI    -- Type/data families
+  -- | A type or data family, with a list of its visible instances
+  | FamilyI 
         Dec
         [InstanceDec]
-
-  | PrimTyConI         -- Ones that can't be expressed with a data type 
-               -- decl, such as (->), Int#
-       Name 
-       Int     -- Arity
-       Bool    -- False => lifted type; True => unlifted
-
+  
+  -- | A \"primitive\" type constructor, which can't be expressed with a 'Dec'. Examples: @(->)@, @Int#@.
+  | PrimTyConI 
+       Name
+       Arity
+       Unlifted
+  
+  -- | A data constructor
   | DataConI 
-       Name    -- The data con itself
-       Type    -- Type of the constructor (fully polymorphic)
-       Name    -- Name of the parent TyCon
-       Fixity
+       Name
+       Type
+       ParentName
+       Fixity
 
+  {- | 
+  A \"value\" variable (as opposed to a type variable, see 'TyVarI').
+  
+  The @Maybe Dec@ field contains @Just@ the declaration which 
+  defined the variable -- including the RHS of the declaration -- 
+  or else @Nothing@, in the case where the RHS is unavailable to
+  the compiler. At present, this value is _always_ @Nothing@:
+  returning the RHS has not yet been implemented because of
+  lack of interest.
+  -}
   | VarI 
-       Name    -- The variable itself
-       Type 
-       (Maybe Dec)     -- Nothing for lambda-bound variables, and 
-                       -- for anything else TH can't figure out
-                       -- E.g. [| let x = 1 in $(do { d <- reify 'x; .. }) |]
-       Fixity
+       Name
+       Type
+       (Maybe Dec)
+       Fixity
 
+  {- | 
+  A type variable.
+  
+  The @Type@ field contains the type which underlies the variable.
+  At present, this is always @'VarT' theName@, but future changes
+  may permit refinement of this.
+  -}
   | TyVarI     -- Scoped type variable
        Name
        Type    -- What it is bound to
   deriving( Show, Data, Typeable )
 
--- | 'InstanceDec' desribes a single instance of a class or type function
+{- | 
+In 'ClassOpI' and 'DataConI', name of the parent class or type
+-}
+type ParentName = Name
+
+-- | In 'PrimTyConI', arity of the type constructor
+type Arity = Int
+
+-- | In 'PrimTyConI', is the type constructor unlifted?
+type Unlifted = Bool
+
+-- | 'InstanceDec' desribes a single instance of a class or type function.
 -- It is just a 'Dec', but guaranteed to be one of the following:
---   InstanceD (with empty [Dec])
---   DataInstD or NewtypeInstD (with empty derived [Name])
---   TySynInstD
+--
+--   * 'InstanceD' (with empty @['Dec']@)
+--
+--   * 'DataInstD' or 'NewtypeInstD' (with empty derived @['Name']@)
+--
+--   * 'TySynInstD'
 type InstanceDec = Dec
 
 data Fixity          = Fixity Int FixityDirection
@@ -707,27 +950,24 @@ data Fixity          = Fixity Int FixityDirection
 data FixityDirection = InfixL | InfixR | InfixN
     deriving( Eq, Show, Data, Typeable )
 
+-- | Highest allowed operator precedence for 'Fixity' constructor (answer: 9)
 maxPrecedence :: Int
 maxPrecedence = (9::Int)
 
+-- | Default fixity: @infixl 9@
 defaultFixity :: Fixity
 defaultFixity = Fixity maxPrecedence InfixL
 
 
------------------------------------------------------
---
---     The main syntax data types
---
------------------------------------------------------
-
-{- $infix #infix#
+{-
 Note [Unresolved infix]
 ~~~~~~~~~~~~~~~~~~~~~~~
-
+-}
+{- $infix #infix#
 When implementing antiquotation for quasiquoters, one often wants
 to parse strings into expressions:
 
-> parse :: String -> Maybe 'Exp'
+> parse :: String -> Maybe Exp
 
 But how should we parse @a + b * c@? If we don't know the fixities of
 @+@ and @*@, we don't know whether to parse it as @a + (b * c)@ or @(a
@@ -782,6 +1022,12 @@ reassociate the tree as necessary.
 
 -}
 
+-----------------------------------------------------
+--
+--     The main syntax data types
+--
+-----------------------------------------------------
+
 data Lit = CharL Char 
          | StringL String 
          | IntegerL Integer     -- ^ Used for overloaded and non-overloaded
@@ -810,10 +1056,10 @@ data Pat
   | InfixP Pat Name Pat           -- ^ @foo ({x :+ y}) = e@
   | UInfixP Pat Name Pat          -- ^ @foo ({x :+ y}) = e@
                                   --
-                                  -- See Note [Unresolved infix] at "Language.Haskell.TH.Syntax#infix"
+                                  -- See "Language.Haskell.TH.Syntax#infix"
   | ParensP Pat                   -- ^ @{(p)}@
                                   --
-                                  -- See Note [Unresolved infix] at "Language.Haskell.TH.Syntax#infix"
+                                  -- See "Language.Haskell.TH.Syntax#infix"
   | TildeP Pat                    -- ^ @{ ~p }@
   | BangP Pat                     -- ^ @{ !p }@
   | AsP Name Pat                  -- ^ @{ x \@ p }@
@@ -832,15 +1078,6 @@ data Clause = Clause [Pat] Body [Dec]
                                   -- ^ @f { p1 p2 = body where decs }@
     deriving( Show, Eq, Data, Typeable )
  
--- | The 'CompE' constructor represents a list comprehension, and 
--- takes a ['Stmt'].  The result expression of the comprehension is
--- the *last* of these, and should be a 'NoBindS'.
---
--- E.g. translation:
---
--- > [ f x | x <- xs ]
---
--- > CompE [BindS (VarP x) (VarE xs), NoBindS (AppE (VarE f) (VarE x))]
 data Exp 
   = VarE Name                          -- ^ @{ x }@
   | ConE Name                          -- ^ @data T1 = C1 t1 t2; p = {C1} e1 e2  @
@@ -848,7 +1085,7 @@ data Exp
   | AppE Exp Exp                       -- ^ @{ f x }@
 
   | InfixE (Maybe Exp) Exp (Maybe Exp) -- ^ @{x + y} or {(x+)} or {(+ x)} or {(+)}@
-    --
+
     -- It's a bit gruesome to use an Exp as the
     -- operator, but how else can we distinguish
     -- constructors from non-constructors?
@@ -857,10 +1094,10 @@ data Exp
 
   | UInfixE Exp Exp Exp                -- ^ @{x + y}@
                                        --
-                                       -- See Note [Unresolved infix] at "Language.Haskell.TH.Syntax#infix"
+                                       -- See "Language.Haskell.TH.Syntax#infix"
   | ParensE Exp                        -- ^ @{ (e) }@
                                        --
-                                       -- See Note [Unresolved infix] at "Language.Haskell.TH.Syntax#infix"
+                                       -- See "Language.Haskell.TH.Syntax#infix"
   | LamE [Pat] Exp                     -- ^ @{ \ p1 p2 -> e }@
   | LamCaseE [Match]                   -- ^ @{ \case m1; m2 }@
   | TupE [Exp]                         -- ^ @{ (e1,e2) }  @
@@ -870,7 +1107,17 @@ data Exp
   | LetE [Dec] Exp                     -- ^ @{ let x=e1;   y=e2 in e3 }@
   | CaseE Exp [Match]                  -- ^ @{ case e of m1; m2 }@
   | DoE [Stmt]                         -- ^ @{ do { p <- e1; e2 }  }@
-  | CompE [Stmt]                       -- ^ @{ [ (x,y) | x <- xs, y <- ys ] }@
+  | CompE [Stmt]                       -- ^ @{ [ (x,y) | x <- xs, y <- ys ] }@ 
+      --
+      -- The result expression of the comprehension is
+      -- the /last/ of the @'Stmt'@s, and should be a 'NoBindS'.
+      --
+      -- E.g. translation:
+      --
+      -- > [ f x | x <- xs ]
+      --
+      -- > CompE [BindS (VarP x) (VarE xs), NoBindS (AppE (VarE f) (VarE x))]
+
   | ArithSeqE Range                    -- ^ @{ [ 1 ,2 .. 10 ] }@
   | ListE [ Exp ]                      -- ^ @{ [1,2,3] }@
   | SigE Exp Type                      -- ^ @{ e :: t }@
@@ -883,13 +1130,15 @@ type FieldExp = (Name,Exp)
 -- Omitted: implicit parameters
 
 data Body
-  = GuardedB [(Guard,Exp)]   -- ^ @f p { | e1 = e2 | e3 = e4 } where ds@
+  = GuardedB [(Guard,Exp)]   -- ^ @f p { | e1 = e2 
+                                 --      | e3 = e4 } 
+                                 -- where ds@
   | NormalB Exp              -- ^ @f p { = e } where ds@
   deriving( Show, Eq, Data, Typeable )
 
 data Guard
-  = NormalG Exp
-  | PatG [Stmt]
+  = NormalG Exp -- ^ @f x { | odd x } = x@
+  | PatG [Stmt] -- ^ @f x { | Just y <- x, Just z <- y } = z@
   deriving( Show, Eq, Data, Typeable )
 
 data Stmt
@@ -918,12 +1167,13 @@ data Dec
   | InstanceD Cxt Type [Dec]      -- ^ @{ instance Show w => Show [w]
                                   --       where ds }@
   | SigD Name Type                -- ^ @{ length :: [a] -> Int }@
-  | ForeignD Foreign
+  | ForeignD Foreign              -- ^ @{ foreign import ... }
+                                  --{ foreign export ... }@
 
   | InfixD Fixity Name            -- ^ @{ infix 3 foo }@
 
   -- | pragmas
-  | PragmaD Pragma                -- ^ @{ {-# INLINE [1] foo #-} }@
+  | PragmaD Pragma                -- ^ @{ {\-# INLINE [1] foo #-\} }@
 
   -- | type families (may also appear in [Dec] of 'ClassD' and 'InstanceD')
   | FamilyD FamFlavour Name 
@@ -988,7 +1238,7 @@ data Con = NormalC Name [StrictType]          -- ^ @C Int a@
 type StrictType = (Strict, Type)
 type VarStrictType = (Name, Strict, Type)
 
-data Type = ForallT [TyVarBndr] Cxt Type  -- ^ @forall <vars>. <ctxt> -> <type>@
+data Type = ForallT [TyVarBndr] Cxt Type  -- ^ @forall \<vars\>. \<ctxt\> -> \<type\>@
           | AppT Type Type                -- ^ @T a b@
           | SigT Type Kind                -- ^ @t :: k@
           | VarT Name                     -- ^ @a@