-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Framework for defaulting superclasses -- -- This small but extensible framework facilitates defining complex -- defaulting rules that are not handled by DefaultSignatures, and -- reducing the overhead of giving instances to new datatypes by -- generating superclasses. One reason we might want this is when a -- superclass wants to be given a default by two different subclasses -- (ex: Bifunctor and Profunctor both could generate Functor instances). -- See the example internal library for how to implement instances of -- Impl. Impl is most valuable when instantiating deep (or even -- undecidably recursive) typeclass hierarchies for multiple new -- datatypes, which is most common in client code. @package impl @version 0.2.0.0 -- | Impl is intended to be used as an alternative to the normal default -- typeclass methods machinery of Haskell. In contrast with -- intrinsic-superclasses, we must specify each link of the -- implementation heirarchy with an instance of Impl, rather than infer -- it from the superclass heirarchy. The benefit of this more explicit -- style is complete control over default methods provided by subclasses, -- at the cost of some automation for the class creator. Impl is most -- valuable when instantiating deep (or even undecidably recursive) -- typeclass hierarchies for multiple new datatypes, which is most common -- in client code. module Impl -- | Typeclasses implementing Impl can build declaratios for their entire -- superclass heirarchy from a collection of required or optional named -- methods, allowing potentially complex logic for defaulting. See the -- example internal library for how to implement instances of -- Impl. class Impl c where { type family Methods c :: [Method Symbol]; } -- | Instantiate the implementing class along with all its superclasses Ex: -- --
-- impl @Monad [t|[]|] -- $$ #return [|\x -> [x]|] -- $$ #bind [|flip concatMap|] --impl :: Impl c => TypeQ -> NamedMethods c :-> DecsQ data Method a Required :: a -> Method a Optional :: a -> Method a -- | (Kind) This is the kind of type-level symbols. Declared here because -- class IP needs it data Symbol -- | Named TH Exps for the class method implementations type NamedMethods c = NamedExpQ (Methods c) -- |
-- >>> :kind! NamedExpQ '[Required "foo", Optional "bar"] -- = '["foo" :! ExpQ,"bar" :? ExpQ] --type family NamedExpQ ss -- | Converts a variable number of arguments into curried form. Ex: -- --
-- >>> :!kind '[Int,String,Double] :-> IO () -- Int -> String -> Double -> IO () --type family as :-> r infixr 0 :-> -- | Infix notation for the type of a named parameter. type (:!) (name :: Symbol) a = NamedF Identity a name -- | Infix notation for the type of an optional named parameter. type (:?) (name :: Symbol) a = NamedF Maybe a name -- | Pass a named (optional or required) argument to a function in any -- order. -- --
-- foo :: ("bar" :! String) -> ("baz" :? Char) -> IO ()
--
--
--
-- >>> foo $$ #baz 'a' :: ("bar" :! String) -> IO ()
--
($$) :: WithParam p fn fn' => fn -> Param p -> fn'
-- | Passing defaults to a function fills all unspecified optional
-- parameters with Nothing:
--
-- -- fn :: "b" :! Bool -> "x" :? Char -> Int -> IO () -- fn ! defaults :: "b" :! Bool -> Int -> IO () --defaults :: Param Defaults -- | arg unwraps a named parameter with the specified name. One way -- to use it is to match on arguments with -XViewPatterns: -- --
-- fn (arg #t -> t) (arg #f -> f) = ... ---- -- This way, the names of parameters can be inferred from the patterns: -- no type signature for fn is required. In case a type -- signature for fn is provided, the parameters must come in the -- same order: -- --
-- fn :: "t" :! Integer -> "f" :! Integer -> ... -- fn (arg #t -> t) (arg #f -> f) = ... -- ok -- fn (arg #f -> f) (arg #t -> t) = ... -- does not typecheck --arg :: () => Name name -> (name :! a) -> a -- | A variation of arg for optional arguments. Requires a default -- value to handle the case when the optional argument was omitted: -- --
-- fn (arg' #answer 42 -> ans) = ... ---- -- In case you want to get a value wrapped in Maybe instead, -- Arg' arg' :: Name name -> a -> (name :? a) -> a data Param p -- | Assign a name to a value of type a wrapped in f. -- --
-- #verbose True :: NamedF Identity Bool "verbose" --data NamedF (f :: Type -> Type) a (name :: Symbol) -- | Retrieve the method names of a typeclass as a typelevel list of -- Method Symbols. A good default for instantiating the -- Methods type, which is robust against changing method names. -- | Deprecated: reify doesn't currently allow introspecting -- default definitions, so they are always Required methodsFor :: Name -> TypeQ -- | Type level list append type family (as :: [x]) ++ (bs :: [x]) :: [x] type TypeQ = Q Type type DecsQ = Q [Dec]