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


-- | Named parameters (keyword arguments) for Haskell
--   
--   <a>named</a> is a lightweight library for named function parameters
--   (keyword arguments) based on overloaded labels. Keyword arguments have
--   several advantages over positional arguments:
--   
--   <ul>
--   <li>they can be supplied in arbitrary order</li>
--   <li>their names serve as documentation at call site</li>
--   <li>it is impossible to accidentally mix them up</li>
--   </ul>
--   
--   Unlike <tt>newtype</tt> wrappers, keyword arguments don't pollute the
--   global namespace, don't require top-level definitions, and don't need
--   to be exported.
--   
--   This implementation of named parameters is typesafe, provides good
--   type inference, descriptive type errors, and has no runtime overhead.
--   
--   Example usage:
--   
--   <pre>
--   import Named
--   
--   createSymLink :: "from" :! FilePath -&gt; "to" :! FilePath -&gt; IO ()
--   createSymLink (Arg from) (Arg to) = ...
--   
--   main = createSymLink ! #from "/path/to/source"
--                        ! #to "/target/path"
--   </pre>
@package named
@version 0.2.0.0

module Named.Internal

-- | Assign a name to a value of type <tt>a</tt> wrapped in <tt>f</tt>.
--   
--   <pre>
--   #verbose True :: NamedF Identity Bool "verbose"
--   </pre>
newtype NamedF f (a :: Type) (name :: Symbol)

-- | Match on an F-argument without specifying its name. See also:
--   <a>argF</a>.
ArgF :: f a -> NamedF f

-- | Match on an argument without specifying its name. See also:
--   <a>arg</a>.
pattern Arg :: a -> name :! a

-- | Infix notation for the type of a named parameter.
type name :! a = NamedF Identity a name

-- | Infix notation for the type of an optional named parameter.
type name :? a = NamedF Maybe a name
class InjValue f
injValue :: InjValue f => a -> f a
newtype Param p
Param :: p -> Param p

-- | Supply a parameter to a function:
--   
--   <pre>
--   function <a>!</a> #param_name value
--   </pre>
--   
--   <pre>
--   function <a>!</a> #x 7 <a>!</a> #y 42 <a>!</a> <a>defaults</a>
--   </pre>
--   
--   This is an infix version of <a>with</a>.
(!) :: forall p fn fn'. WithParam p fn fn' => fn -> Param p -> fn'
infixl 9 !

-- | Supply a parameter <tt>p</tt> to a function <tt>fn</tt>, resulting in
--   <tt>fn'</tt>.
--   
--   For example, when we pass a single named parameter, we get a function
--   without this parameter:
--   
--   <pre>
--   WithParam
--                    ("x" :! Char)       -- p
--     ("b" :! Bool -&gt; "x" :! Char -&gt; r)  -- fn
--     ("b" :! Bool                -&gt; r)  -- fn'
--   </pre>
--   
--   In case the parameter cannot be supplied, this constraint will become
--   a type error.
class WithParam p fn fn' | p fn -> fn'

-- | Supply a parameter to a function:
--   
--   <pre>
--   <a>with</a> (#param_name value) function
--   
--   </pre>
--   
--   <pre>
--   <a>with</a> <a>defaults</a> function
--   
--   </pre>
--   
--   This is a prefix version of the (<a>!</a>) operator.
with :: WithParam p fn fn' => Param p -> fn -> fn'
data Defaults
Defaults :: Defaults

-- | Passing <a>defaults</a> to a function fills all unspecified optional
--   parameters with <a>Nothing</a>:
--   
--   <pre>
--   fn            :: "b" <a>:!</a> Bool -&gt; "x" <a>:?</a> Char -&gt; Int -&gt; IO ()
--   fn <a>!</a> <a>defaults</a> :: "b" <a>:!</a> Bool -&gt;                Int -&gt; IO ()
--   </pre>
defaults :: Param Defaults

-- | A proxy for a name, intended for use with <tt>-XOverloadedLabels</tt>:
--   
--   <pre>
--   #verbose :: Name "verbose"
--   </pre>
data Name (name :: Symbol)
Name :: Name

-- | <a>arg</a> unwraps a named parameter with the specified name. One way
--   to use it is to match on arguments with <tt>-XViewPatterns</tt>:
--   
--   <pre>
--   fn (arg #t -&gt; t) (arg #f -&gt; f) = ...
--   </pre>
--   
--   This way, the names of parameters can be inferred from the patterns:
--   no type signature for <tt>fn</tt> is required. In case a type
--   signature for <tt>fn</tt> is provided, the parameters must come in the
--   same order:
--   
--   <pre>
--   fn :: "t" :! Integer -&gt; "f" :! Integer -&gt; ...
--   fn (arg #t -&gt; t) (arg #f -&gt; f) = ... -- ok
--   fn (arg #f -&gt; f) (arg #t -&gt; t) = ... -- does not typecheck
--   </pre>
arg :: Name name -> (name :! a) -> a

-- | <a>argF</a> is similar to <a>arg</a>: it unwraps a named parameter
--   with the specified name. The difference is that the result of
--   <a>argF</a> is inside an arity wrapper, which is <a>Identity</a> for
--   normal parameters and <a>Maybe</a> for optional parameters.
argF :: Name name -> NamedF f a name -> f a

-- | A variation of <a>arg</a> for optional arguments. Requires a default
--   value to handle the case when the optional argument was omitted:
--   
--   <pre>
--   fn (argDef #answer 42 -&gt; ans) = ...
--   </pre>
--   
--   In case you want to get a value wrapped in <a>Maybe</a> instead, use
--   <a>argF</a> or <a>ArgF</a>.
argDef :: Name name -> a -> (name :? a) -> a
data DApply
data DFill
data DPass
type family Decide (p :: Type) (fn :: Type) :: [Type]
class WithParam' (ds :: [Type]) p fn fn' | ds p fn -> fn'
withParam :: WithParam' ds p fn fn' => p -> fn -> fn'
instance Named.Internal.WithParam' (Named.Internal.Decide p fn) p fn fn' => Named.Internal.WithParam p fn fn'
instance (fn Data.Type.Equality.~ fn') => Named.Internal.WithParam' '[] p fn fn'
instance (Named.Internal.WithParam' ds p r r', fn Data.Type.Equality.~ (p -> r), fn' Data.Type.Equality.~ r') => Named.Internal.WithParam' (Named.Internal.DApply : ds) p fn fn'
instance (Named.Internal.WithParam' ds p r r', fn Data.Type.Equality.~ (x -> r), fn' Data.Type.Equality.~ (x -> r')) => Named.Internal.WithParam' (Named.Internal.DPass : ds) p fn fn'
instance (Named.Internal.WithParam' ds p r r', fn Data.Type.Equality.~ (Named.Internal.NamedF f x name -> r), fn' Data.Type.Equality.~ r', f Data.Type.Equality.~ GHC.Maybe.Maybe) => Named.Internal.WithParam' (Named.Internal.DFill : ds) p fn fn'
instance (name Data.Type.Equality.~ name') => GHC.OverloadedLabels.IsLabel name' (Named.Internal.Name name)
instance (p Data.Type.Equality.~ Named.Internal.NamedF f a name, Named.Internal.InjValue f) => GHC.OverloadedLabels.IsLabel name (a -> Named.Internal.Param p)
instance Named.Internal.InjValue Data.Functor.Identity.Identity
instance Named.Internal.InjValue GHC.Maybe.Maybe
instance (name Data.Type.Equality.~ name', a Data.Type.Equality.~ a', Named.Internal.InjValue f) => GHC.OverloadedLabels.IsLabel name (a -> Named.Internal.NamedF f a' name')


-- | Named parameters, also known as keyword arguments, have several
--   advantages over positional arguments:
--   
--   <ul>
--   <li>convenience: they can be supplied in arbitrary order</li>
--   <li>readability: their names serve as documentation at call site</li>
--   <li>safety: it is impossible to accidentally mix them up</li>
--   </ul>
--   
--   Consider a function to replace a substring with another string:
--   
--   <pre>
--   Text.replace path "$HOME" "/home/username/"
--   </pre>
--   
--   We want to replace references to the <tt>$HOME</tt> environment
--   variable with a concrete directory. There is but one problem – we have
--   supplied the text arguments in the wrong order.
--   
--   Compare that to a newtype-based solution:
--   
--   <pre>
--   Text.replace
--     (Needle "$HOME")
--     (Replacement "/home/username/")
--     (Haystack path)
--   </pre>
--   
--   Now that the function requires each argument to be wrapped in a
--   newtype, we cannot mix them up – the compiler will report an error,
--   and newtype constructors serve as documentation.
--   
--   The problem with newtypes is that it is bothersome to create them for
--   each parameter, they pollute the global namespace, and we still cannot
--   supply wrapped arguments in arbitrary order.
--   
--   With keyword arguments, none of that is a problem:
--   
--   <pre>
--   Text.replace <a>!</a> #haystack path
--                <a>!</a> #needle "$HOME"
--                <a>!</a> #replacement "/home/username/"
--   </pre>
--   
--   Functions can declare their parameter names in pattern bindings:
--   
--   <pre>
--   replace (<a>arg</a> #needle -&gt; n) (<a>arg</a> #replacement -&gt; r) (<a>arg</a> #haystack -&gt; h) =
--     ...
--   </pre>
--   
--   Types are inferred, but it is possible to specify them. When the
--   parameter names are specified in the type signature, they can be
--   omitted from the pattern bindings:
--   
--   <pre>
--   replace ::
--     "needle"      <a>:!</a> Text -&gt;
--     "replacement" <a>:!</a> Text -&gt;
--     "haystack"    <a>:!</a> Text -&gt;
--     Text
--   replace (<a>Arg</a> n) (<a>Arg</a> r) (<a>Arg</a> h) =
--     ...
--   </pre>
--   
--   Keyword arguments have seamless interoperability with positional
--   arguments when the function takes them last. Consider this function:
--   
--   <pre>
--   foo :: A -&gt; B -&gt; "x" :! C -&gt; IO ()
--   </pre>
--   
--   There are several ways to invoke it:
--   
--   <pre>
--   (foo a b) <a>!</a> #x c     -- parentheses for clarity
--   (foo a <a>!</a> #x c) b     -- parentheses required
--   (foo <a>!</a> #x c) a b     -- parentheses required
--   </pre>
--   
--   We can also supply keyword arguments using the <a>with</a> combinator
--   instead of the <a>!</a> operator:
--   
--   <pre>
--   (<a>with</a> (#x c) foo) a b  -- parentheses for clarity
--   <a>with</a> (#x c) (foo a b)  -- has the same effect
--   </pre>
--   
--   Both <a>!</a> and <a>with</a> work in a similar manner: they traverse
--   the spine of the function and supply the first keyword argument with a
--   matching name.
--   
--   For example:
--   
--   <pre>
--   bar             :: "x" :! A -&gt; "y" :! B -&gt; IO ()
--   bar <a>!</a> #y b      :: "x" :! A             -&gt; IO ()
--   <a>with</a> (#y b) bar :: "x" :! A             -&gt; IO ()
--   </pre>
--   
--   There is also support for optional parameters. A function can specify
--   default values for some of its arguments:
--   
--   <pre>
--   log ::
--     "message"  <a>:!</a> Text -&gt;
--     "severity" <a>:?</a> Severity -&gt;
--     "handle"   <a>:?</a> Handle -&gt;
--     IO ()
--   log (<a>arg</a>    #message          -&gt; msg)
--       (<a>argDef</a> #severity Error   -&gt; sev)
--       (<a>argDef</a> #handle   stderr  -&gt; hndl)
--     = ...
--   </pre>
--   
--   Optional parameters are denoted with (<a>:?</a>) instead of
--   (<a>:!</a>). Instead of <a>arg</a> to match on them, we must use
--   either <a>argDef</a> to provide a default value or <a>argF</a> to get
--   a value wrapped in <a>Maybe</a> (<a>Just</a> when the parameter was
--   specified, <a>Nothing</a> when omitted).
--   
--   At call site, optional parameters are passed using the same (<a>!</a>)
--   operator:
--   
--   <pre>
--   log <a>!</a> #message "All your base are belong to us"
--       <a>!</a> #severity Info
--       <a>!</a> #handle stdout
--   </pre>
--   
--   To use the default values for all unspecified optional parameters, we
--   can pass <a>defaults</a> to the function:
--   
--   <pre>
--   log <a>!</a> #message "Could not match type <a>Int</a> with type <a>Bool</a>"
--       <a>!</a> <a>defaults</a>
--   </pre>
--   
--   <pre>
--   log <a>!</a> #message "The password must contain a letter, \
--                  \a digit, and a plot twist"
--       <a>!</a> #severity Warning
--       <a>!</a> <a>defaults</a>
--   </pre>
--   
--   We can also pass <a>defaults</a> using <a>with</a>, which has the same
--   effect as the (<a>!</a>) operator:
--   
--   <pre>
--   <a>with</a> <a>defaults</a> $
--     log <a>!</a> #message "Connection interrupted"
--         <a>!</a> #handle logfile
--   </pre>
module Named

-- | Supply a parameter to a function:
--   
--   <pre>
--   function <a>!</a> #param_name value
--   </pre>
--   
--   <pre>
--   function <a>!</a> #x 7 <a>!</a> #y 42 <a>!</a> <a>defaults</a>
--   </pre>
--   
--   This is an infix version of <a>with</a>.
(!) :: forall p fn fn'. WithParam p fn fn' => fn -> Param p -> fn'
infixl 9 !

-- | Supply a parameter <tt>p</tt> to a function <tt>fn</tt>, resulting in
--   <tt>fn'</tt>.
--   
--   For example, when we pass a single named parameter, we get a function
--   without this parameter:
--   
--   <pre>
--   WithParam
--                    ("x" :! Char)       -- p
--     ("b" :! Bool -&gt; "x" :! Char -&gt; r)  -- fn
--     ("b" :! Bool                -&gt; r)  -- fn'
--   </pre>
--   
--   In case the parameter cannot be supplied, this constraint will become
--   a type error.
class WithParam p fn fn' | p fn -> fn'

-- | Supply a parameter to a function:
--   
--   <pre>
--   <a>with</a> (#param_name value) function
--   
--   </pre>
--   
--   <pre>
--   <a>with</a> <a>defaults</a> function
--   
--   </pre>
--   
--   This is a prefix version of the (<a>!</a>) operator.
with :: WithParam p fn fn' => Param p -> fn -> fn'

-- | Passing <a>defaults</a> to a function fills all unspecified optional
--   parameters with <a>Nothing</a>:
--   
--   <pre>
--   fn            :: "b" <a>:!</a> Bool -&gt; "x" <a>:?</a> Char -&gt; Int -&gt; IO ()
--   fn <a>!</a> <a>defaults</a> :: "b" <a>:!</a> Bool -&gt;                Int -&gt; IO ()
--   </pre>
defaults :: Param Defaults

-- | Infix notation for the type of a named parameter.
type name :! a = NamedF Identity a name

-- | Infix notation for the type of an optional named parameter.
type name :? a = NamedF Maybe a name

-- | Assign a name to a value of type <tt>a</tt> wrapped in <tt>f</tt>.
--   
--   <pre>
--   #verbose True :: NamedF Identity Bool "verbose"
--   </pre>
data NamedF f (a :: Type) (name :: Symbol)

-- | A proxy for a name, intended for use with <tt>-XOverloadedLabels</tt>:
--   
--   <pre>
--   #verbose :: Name "verbose"
--   </pre>
data Name (name :: Symbol)
Name :: Name

-- | <a>arg</a> unwraps a named parameter with the specified name. One way
--   to use it is to match on arguments with <tt>-XViewPatterns</tt>:
--   
--   <pre>
--   fn (arg #t -&gt; t) (arg #f -&gt; f) = ...
--   </pre>
--   
--   This way, the names of parameters can be inferred from the patterns:
--   no type signature for <tt>fn</tt> is required. In case a type
--   signature for <tt>fn</tt> is provided, the parameters must come in the
--   same order:
--   
--   <pre>
--   fn :: "t" :! Integer -&gt; "f" :! Integer -&gt; ...
--   fn (arg #t -&gt; t) (arg #f -&gt; f) = ... -- ok
--   fn (arg #f -&gt; f) (arg #t -&gt; t) = ... -- does not typecheck
--   </pre>
arg :: Name name -> (name :! a) -> a

-- | A variation of <a>arg</a> for optional arguments. Requires a default
--   value to handle the case when the optional argument was omitted:
--   
--   <pre>
--   fn (argDef #answer 42 -&gt; ans) = ...
--   </pre>
--   
--   In case you want to get a value wrapped in <a>Maybe</a> instead, use
--   <a>argF</a> or <a>ArgF</a>.
argDef :: Name name -> a -> (name :? a) -> a

-- | <a>argF</a> is similar to <a>arg</a>: it unwraps a named parameter
--   with the specified name. The difference is that the result of
--   <a>argF</a> is inside an arity wrapper, which is <a>Identity</a> for
--   normal parameters and <a>Maybe</a> for optional parameters.
argF :: Name name -> NamedF f a name -> f a

-- | Match on an argument without specifying its name. See also:
--   <a>arg</a>.
pattern Arg :: a -> name :! a

-- | Match on an F-argument without specifying its name. See also:
--   <a>argF</a>.
pattern ArgF :: () => f a -> NamedF f a name
