-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Template Haskell hack to violate module abstractions
--   
--   <a>Knowing a true name gives one power over its owner</a>.
--   
--   A Template Haskell hack to get unexported <tt>Name</tt>s―be they
--   types, data constructors, record fields or class methods―a slightly
--   less unsafe way to violate another module's abstractions than
--   <tt>unsafeCoerce</tt>.
--   
--   A few <a>quick examples</a>.
--   
--   I'm too lazy to keep a changelog, but I do write <a>detailed commit
--   messages</a>.
@package true-name
@version 0.1.0.3


-- | Refer to <a>these examples</a>.
module Unsafe.TrueName

-- | Summons a <a>Name</a> using <tt>template-haskell</tt>'s <a>reify</a>
--   function.
--   
--   The first argument is a <a>String</a> matching the <a>Name</a> we
--   want: either its <a>nameBase</a>, or qualified with its module. The
--   second argument gives the <a>Name</a> to <a>reify</a>.
--   
--   If no match is found or there is some ambiguity, <a>summon</a> will
--   fail with a list of <a>Name</a>s found, along with the output of
--   <a>reify</a> for reference.
--   
--   Suppose we are given a module <tt>M</tt> that exports a function
--   <tt>s</tt>, but not the type <tt>T</tt>, the constrcutor <tt>C</tt>,
--   nor the field <tt>f</tt>:
--   
--   <pre>
--   module M (s) where
--   newtype T = C { f :: Int }
--   s :: T -&gt; T
--   s = C . succ . f
--   </pre>
--   
--   In our own module we have no legitimate way of passing <tt>s</tt> an
--   argument of type <tt>T</tt>. We can get around this in a type-safe way
--   with <a>summon</a>:
--   
--   <pre>
--   {-# LANGUAGE TemplateHaskell #-}
--   module Main where
--   import Language.Haskell.TH.Syntax
--   import Unsafe.TrueName
--   import M
--   
--   type T = $(fmap ConT $ summon "T" 's)
--   mkC :: Int -&gt; T; unC :: T -&gt; Int; f :: T -&gt; Int
--   mkC = $(fmap ConE $ summon "C" =&lt;&lt; summon "T" 's)
--   unC $(fmap (`ConP` [VarP $ mkName "n"]) $ summon "C" =&lt;&lt; summon "T" 's) = n
--   f = $(fmap VarE $ summon "f" =&lt;&lt; summon "T" 's)
--   
--   main :: IO ()
--   main = print (unC t, n) where
--       t = s (mkC 42 :: T)
--       n = f (s t)
--   </pre>
--   
--   Note that <a>summon</a> cannot obtain the <a>Name</a> for an
--   unexported function, since GHC <a>does not currently return the RHS of
--   function definitons</a>. The only workaround is to copypasta the
--   definition. D:
summon :: String -> Name -> Q Name

-- | A more convenient <a>QuasiQuoter</a> interface to <a>summon</a>.
--   
--   The first space-delimited token gives the initial <a>Name</a> passed
--   to <a>summon</a>: it must be ‘quoted’ with a <tt>'</tt> or <tt>''</tt>
--   prefix to indicate whether it should be interpreted in an expression
--   or a type context, as per <a>the usual TH syntax</a>. Subsequent
--   tokens correspond to the <a>String</a> argument of <a>summon</a>, and
--   are iterated over. Thus
--   
--   <pre>
--   [truename| ''A B C D |]
--   </pre>
--   
--   is roughly equivalent to:
--   
--   <pre>
--   summon "D" =&lt;&lt; summon "C" =&lt;&lt; summon "B" ''A
--   </pre>
--   
--   but with the resulting <a>Name</a> wrapped up in <a>ConE</a>,
--   <a>VarE</a>, <a>ConP</a>, or <a>ConT</a>, depending on the context.
--   (There is no <a>quoteDec</a>.)
--   
--   Variable bindings are given after a <tt>|</tt> token in a <a>Pat</a>
--   context:
--   
--   <pre>
--   [truename| ''Chan Chan | chanR chanW |] &lt;- newChan
--   </pre>
--   
--   These may be prefixed with <tt>!</tt> or <tt>~</tt> to give the usual
--   semantics. A single <tt>..</tt> token invokes <tt>RecordWildCards</tt>
--   in <a>Pat</a> contexts, and for record construction in <a>Exp</a>
--   contexts. Nested or more exotic patterns are not supported.
--   
--   With this, the example from <a>summon</a> may be more succinctly
--   written:
--   
--   <pre>
--   {-# LANGUAGE QuasiQuotes #-}
--   module Main where
--   import Unsafe.TrueName
--   import M
--   
--   type T = [truename| 's T |]
--   mkC :: Int -&gt; T; unC :: T -&gt; Int; f :: T -&gt; Int
--   mkC = [truename| 's T C |]
--   unC [truename| 's T C | n |] = n
--   f = [truename| 's T f |]
--   
--   main :: IO ()
--   main = print (unC t, n) where
--       t = s (mkC 42 :: T)
--       n = f (s t)
--   </pre>
truename :: QuasiQuoter
