-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | simple alternative to type classes -- @package cluss @version 0.2 -- | Basic tools for clusses. Examples show how to use them. -- -- Template haskell tools are in the module Type.Cluss.TH. module Type.Cluss -- | In as is a cluss, where as is a list -- of type patterns. Normally, as is concrete and does not -- contain any type variables, like In [Binary (->) -- (Show >|< This), Type String] -- a. -- -- When a satisfies In as a, you can use the method -- proj :: AllOf as f -> f a. -- -- Internally, "type pattern matching" is executed by Where, a closed -- type family, which cannot check if a type satisfies a constraint. If -- as has many type patterns that can match a, only the -- first one matches a. -- -- Clusses call for some language extensions. Basically, this language -- pragma will do. -- --
-- {-# LANGUAGE DataKinds, FlexibleContexts, TypeOperators #-}
--
class In (as :: [*]) (a :: k)
proj :: In as a => AllOf as t -> t a
-- | Has as a judges whether a type a belongs to a
-- cluss In as, on some level. When not sure, Has
-- always returns True. For example, when as has
-- Unary [] Show and a is [b],
-- Has can't judge if b belongs to Show since the
-- instances of Show is open, but it assumes that
-- b belongs to Show and returns True.
-- | The empty type Type a is a type pattern, where
-- a is a type. The type pattern Type Int
-- corresponds to instance C Int where ... (where
-- C is a corresponding type class), for example. Note that the
-- type variable a can be of any kind: a could be of
-- the kind * -> *, for example.
data Type (a :: k)
-- | The empty type AnyType p is a type pattern, where
-- p is a type function from a type to a constraint. The type
-- pattern AnyType Show basically corresponds to
-- instance Show a => C a where ... (where C
-- is a corresponding type class), for example, but AnyType is
-- much more useful in that it does not cause overlapping
-- instances whereas C is likely to, because cluss instances
-- are prioritized.
data AnyType (p :: k -> Constraint)
-- | The empty type a <| p is a type pattern, where
-- a is a type constructor, and p is a type function to
-- a constraint from the type variables for the constructor a.
-- The type pattern [] <| Show corresponds to
-- instance Show a => C [a] where ... (where
-- C is a corresponding type class), for example.
--
-- You can replace Unary, Binary, ..., and Denary
-- with <|, but you can sometimes save the effort of
-- annotating kinds using Unary, Binary, ..., or
-- Denary instead of <|, especially when using the
-- PolyKinds extension, because the kinds of the parameters in
-- Unary, Binary, ..., and Denary are restricted as
-- described below.
data (<|) (a :: k) (p :: l)
-- | a <| p, with a being of the kind i ->
-- k, and p of the kind i -> Constraint.
type Unary (a :: i -> k) (p :: i -> Constraint) = a <| p
-- | a <| p, with a being of the kind i -> i2
-- -> k, and p of the kind i -> i2 ->
-- Constraint.
type Binary (a :: i -> i2 -> k) (p :: i -> i2 -> Constraint) = a <| p
-- | a <| p, with a being of the kind i -> i2
-- -> i3 -> k, and p of the kind i -> i2 ->
-- i3 -> Constraint.
type Ternary (a :: i -> i2 -> i3 -> k) (p :: i -> i2 -> i3 -> Constraint) = a <| p
-- | a <| p, with a being of the kind i -> i2
-- -> i3 -> i4 -> k, and p of the kind i ->
-- i2 -> i3 -> i4 -> Constraint.
type Quaternary (a :: i -> i2 -> i3 -> i4 -> k) (p :: i -> i2 -> i3 -> i4 -> Constraint) = a <| p
-- | a <| p, with a being of the kind i -> i2
-- -> i3 -> i4 -> i5 -> k, and p of the kind
-- i -> i2 -> i3 -> i4 -> i5 ->
-- Constraint.
type Quinary (a :: i -> i2 -> i3 -> i4 -> i5 -> k) (p :: i -> i2 -> i3 -> i4 -> i5 -> Constraint) = a <| p
-- | a <| p, with a being of the kind i -> i2
-- -> i3 -> i4 -> i5 -> i6 -> k, and p of
-- the kind i -> i2 -> i3 -> i4 -> i5 -> i6 ->
-- Constraint.
type Senary (a :: i -> i2 -> i3 -> i4 -> i5 -> i6 -> k) (p :: i -> i2 -> i3 -> i4 -> i5 -> i6 -> Constraint) = a <| p
-- | a <| p, with a being of the kind i -> i2
-- -> i3 -> i4 -> i5 -> i6 -> i7 -> k, and
-- p of the kind i -> i2 -> i3 -> i4 -> i5 ->
-- i6 -> i7 -> Constraint.
type Septenary (a :: i -> i2 -> i3 -> i4 -> i5 -> i6 -> i7 -> k) (p :: i -> i2 -> i3 -> i4 -> i5 -> i6 -> i7 -> Constraint) = a <| p
-- | a <| p, with a being of the kind i -> i2
-- -> i3 -> i4 -> i5 -> i6 -> i7 -> i8 -> k,
-- and p of the kind i -> i2 -> i3 -> i4 -> i5
-- -> i6 -> i7 -> i8 -> Constraint.
type Octary (a :: i -> i2 -> i3 -> i4 -> i5 -> i6 -> i7 -> i8 -> k) (p :: i -> i2 -> i3 -> i4 -> i5 -> i6 -> i7 -> i8 -> Constraint) = a <| p
-- | a <| p, with a being of the kind i -> i2
-- -> i3 -> i4 -> i5 -> i6 -> i7 -> i8 -> i9 ->
-- k, and p of the kind i -> i2 -> i3 -> i4
-- -> i5 -> i6 -> i7 -> i8 -> i9 ->
-- Constraint.
type Nonary (a :: i -> i2 -> i3 -> i4 -> i5 -> i6 -> i7 -> i8 -> i9 -> k) (p :: i -> i2 -> i3 -> i4 -> i5 -> i6 -> i7 -> i8 -> i9 -> Constraint) = a <| p
-- | a <| p, with a being of the kind i -> i2
-- -> i3 -> i4 -> i5 -> i6 -> i7 -> i8 -> i9 ->
-- i10 -> k, and p of the kind i -> i2 -> i3
-- -> i4 -> i5 -> i6 -> i7 -> i8 -> i9 -> i10 ->
-- Constraint.
type Denary (a :: i -> i2 -> i3 -> i4 -> i5 -> i6 -> i7 -> i8 -> i9 -> i10 -> k) (p :: i -> i2 -> i3 -> i4 -> i5 -> i6 -> i7 -> i8 -> i9 -> i10 -> Constraint) = a <| p
-- | AllOf as f is a tuple that contains values of the type
-- f a, where a can be any type that satisfies In
-- as a. Each value corresponds to each type pattern, and the values
-- in AllOf as f must be in the same order as the type
-- patterns in as. And, And1, And2, ..., and And10 are used to
-- combine the values, where None must be added at the end. You have to
-- use And for Type a, And1 for Unary a
-- p, And2 for Binary a p, ..., and And10 for
-- Denary a p.
type AllOf as = AllOf' as as
-- | This creates a recursion. In other words, This will work
-- as In as itself when used in the type list (first
-- parameter) as of In, combined with Type,
-- <|, Unary, Binary, ..., Denary,
-- >+<, >++<, ..., >++++++++++<, >|<, >||<,
-- ..., and >|||||||||<.
--
-- Note that This will not be expanded into In as
-- if the condition described above is not satisfied. For example,
-- This in the parameter of AnyType will not be expanded
-- because it causes infinite recursion. Internally, the expansion is
-- executed by Modify, Modify2, ..., and Modify10.
--
-- The instance of This itself cannot be created since the context
-- True ~ False will never be satisfied.
--
-- There is no predetermined limit of recursion depth, but GHC has a
-- fixed-depth recursion stack for safety, so you may need to increase
-- the stack depth with -fcontext-stack=N.
class True ~ False => This (a :: k)
-- | Pure a is equivalent to the empty constraint
-- ().
--
-- -- Pure a == () --class Pure (a :: i) -- |
-- (Is a) b == (a ~ b) --type Is = (~) -- |
-- (p >+< q) a == (p a, q a) --class (p a, q a) => (>+<) p q a -- |
-- (p >++< q) a b == (p a b, q a b) --class (p a b, q a b) => (>++<) p q a b -- |
-- (p >+++< q) a b c == (p a b c, q a b c) --class (p a b c, q a b c) => (>+++<) p q a b c -- |
-- (p >++++< q) a b c d == (p a b c d, q a b c d) --class (p a b c d, q a b c d) => (>++++<) p q a b c d -- |
-- (p >+++++< q) a b c d e == (p a b c d e, q a b c d e) --class (p a b c d e, q a b c d e) => (>+++++<) p q a b c d e -- |
-- (p >++++++< q) a b c d e f == (p a b c d e f, q a b c d e f) --class (p a b c d e f, q a b c d e f) => (>++++++<) p q a b c d e f -- |
-- (p >+++++++< q) a b c d e f g == (p a b c d e f g, q a b c d e f g) --class (p a b c d e f g, q a b c d e f g) => (>+++++++<) p q a b c d e f g -- |
-- (p >++++++++< q) a b c d e f g h == (p a b c d e f g h, q a b c d e f g h) --class (p a b c d e f g h, q a b c d e f g h) => (>++++++++<) p q a b c d e f g h -- |
-- (p >+++++++++< q) a b c d e f g h i == (p a b c d e f g h, q a b c d e f g h i) --class (p a b c d e f g h i, q a b c d e f g h i) => (>+++++++++<) p q a b c d e f g h i -- |
-- (p >++++++++++< q) a b c d e f g h i j == (p a b c d e f g h, q a b c d e f g h i j) --class (p a b c d e f g h i j, q a b c d e f g h i j) => (>++++++++++<) p q a b c d e f g h i j -- |
-- (p >|< q) a b == (p a, q b) --class (p a, q b) => (>|<) p q a b -- |
-- (p >||< q) a b c == (p a b, q c) --class (p a b, q c) => (>||<) p q a b c -- |
-- (p >|||< q) a b c d == (p a b c, q d) --class (p a b c, q d) => (>|||<) p q a b c d -- |
-- (p >||||< q) a b c d e == (p a b c d, q e) --class (p a b c d, q e) => (>||||<) p q a b c d e -- |
-- (p >|||||< q) a b c d e f == (p a b c d e, q f) --class (p a b c d e, q f) => (>|||||<) p q a b c d e f -- |
-- (p >||||||< q) a b c d e f g == (p a b c d e f, q g) --class (p a b c d e f, q g) => (>||||||<) p q a b c d e f g -- |
-- (p >|||||||< q) a b c d e f g h == (p a b c d e f g, q h) --class (p a b c d e f g, q h) => (>|||||||<) p q a b c d e f g h -- |
-- (p >||||||||< q) a b c d e f g h i == (p a b c d e f g h, q i) --class (p a b c d e f g h, q i) => (>||||||||<) p q a b c d e f g h i -- |
-- (p >||||||||< q) a b c d e f g h i j == (p a b c d e f g h i, q j) --class (p a b c d e f g h i, q j) => (>|||||||||<) p q a b c d e f g h i j type AllOfI as = AllOfI' as as andI :: a -> AllOfI' ts as -> AllOfI' ts (Type a : as) andI1 :: (forall b. Modify (a b) (In ts) p b => a b) -> AllOfI' ts as -> AllOfI' ts (Unary a p : as) andI2 :: (forall b c. Modify2 (a b c) (In ts) p b c => a b c) -> AllOfI' ts as -> AllOfI' ts (Binary a p : as) andI3 :: (forall b c d. Modify3 (a b c d) (In ts) p b c d => a b c d) -> AllOfI' ts as -> AllOfI' ts (Ternary a p : as) andI4 :: (forall b c d e. Modify4 (a b c d e) (In ts) p b c d e => a b c d e) -> AllOfI' ts as -> AllOfI' ts (Quaternary a p : as) andI5 :: (forall b c d e f. Modify5 (a b c d e f) (In ts) p b c d e f => a b c d e f) -> AllOfI' ts as -> AllOfI' ts (Quinary a p : as) andI6 :: (forall b c d e f g. Modify6 (a b c d e f g) (In ts) p b c d e f g => a b c d e f g) -> AllOfI' ts as -> AllOfI' ts (Senary a p : as) andI7 :: (forall b c d e f g h. Modify7 (a b c d e f g h) (In ts) p b c d e f g h => a b c d e f g h) -> AllOfI' ts as -> AllOfI' ts (Septenary a p : as) andI8 :: (forall b c d e f g h i. Modify8 (a b c d e f g h i) (In ts) p b c d e f g h i => a b c d e f g h i) -> AllOfI' ts as -> AllOfI' ts (Octary a p : as) andI9 :: (forall b c d e f g h i j. Modify9 (a b c d e f g h i j) (In ts) p b c d e f g h i j => a b c d e f g h i j) -> AllOfI' ts as -> AllOfI' ts (Nonary a p : as) andI10 :: (forall b c d e f g h i j k. Modify10 (a b c d e f g h i j k) (In ts) p b c d e f g h i j k => a b c d e f g h i j k) -> AllOfI' ts as -> AllOfI' ts (Denary a p : as) noneI :: AllOfI' ts [] projI :: In as a => AllOfI as -> a type AllOfF as t = AllOfF' as as t andF :: (a -> t) -> AllOfF' ts as t -> AllOfF' ts (Type a : as) t andF1 :: (forall b. Modify (a b) (In ts) p b => a b -> t) -> AllOfF' ts as t -> AllOfF' ts (Unary a p : as) t andF2 :: (forall b c. Modify2 (a b c) (In ts) p b c => a b c -> t) -> AllOfF' ts as t -> AllOfF' ts (Binary a p : as) t andF3 :: (forall b c d. Modify3 (a b c d) (In ts) p b c d => a b c d -> t) -> AllOfF' ts as t -> AllOfF' ts (Ternary a p : as) t andF4 :: (forall b c d e. Modify4 (a b c d e) (In ts) p b c d e => a b c d e -> t) -> AllOfF' ts as t -> AllOfF' ts (Quaternary a p : as) t andF5 :: (forall b c d e f. Modify5 (a b c d e f) (In ts) p b c d e f => a b c d e f -> t) -> AllOfF' ts as t -> AllOfF' ts (Quinary a p : as) t andF6 :: (forall b c d e f g. Modify6 (a b c d e f g) (In ts) p b c d e f g => a b c d e f g -> t) -> AllOfF' ts as t -> AllOfF' ts (Senary a p : as) t andF7 :: (forall b c d e f g h. Modify7 (a b c d e f g h) (In ts) p b c d e f g h => a b c d e f g h -> t) -> AllOfF' ts as t -> AllOfF' ts (Septenary a p : as) t andF8 :: (forall b c d e f g h i. Modify8 (a b c d e f g h i) (In ts) p b c d e f g h i => a b c d e f g h i -> t) -> AllOfF' ts as t -> AllOfF' ts (Octary a p : as) t andF9 :: (forall b c d e f g h i j. Modify9 (a b c d e f g h i j) (In ts) p b c d e f g h i j => a b c d e f g h i j -> t) -> AllOfF' ts as t -> AllOfF' ts (Nonary a p : as) t andF10 :: (forall b c d e f g h i j k. Modify10 (a b c d e f g h i j k) (In ts) p b c d e f g h i j k => a b c d e f g h i j k -> t) -> AllOfF' ts as t -> AllOfF' ts (Denary a p : as) t noneF :: AllOfF' ts [] t projF :: In as a => AllOfF as t -> (a -> t) instance In' n ts as a => In' (Look_At_Tail n) ts (Denary b p : as) a instance In' n ts as a => In' (Look_At_Tail n) ts (Nonary b p : as) a instance In' n ts as a => In' (Look_At_Tail n) ts (Octary b p : as) a instance In' n ts as a => In' (Look_At_Tail n) ts (Septenary b p : as) a instance In' n ts as a => In' (Look_At_Tail n) ts (Senary b p : as) a instance In' n ts as a => In' (Look_At_Tail n) ts (Quinary b p : as) a instance In' n ts as a => In' (Look_At_Tail n) ts (Quaternary b p : as) a instance In' n ts as a => In' (Look_At_Tail n) ts (Ternary b p : as) a instance In' n ts as a => In' (Look_At_Tail n) ts (Binary b p : as) a instance In' n ts as a => In' (Look_At_Tail n) ts (Unary b p : as) a instance In' n ts as a => In' (Look_At_Tail n) ts (AnyType p : as) a instance In' n ts as a => In' (Look_At_Tail n) ts (Type b : as) a instance (Modify10 (a b c d e f g h i j k11) (In ts) p b c d e f g h i j k11) => In' Look_At_Head ts (Denary a p : as) (a b c d e f g h i j k11) instance (Modify9 (a b c d e f g h i j) (In ts) p b c d e f g h i j) => In' Look_At_Head ts (Nonary a p : as) (a b c d e f g h i j) instance (Modify8 (a b c d e f g h i) (In ts) p b c d e f g h i) => In' Look_At_Head ts (Octary a p : as) (a b c d e f g h i) instance (Modify7 (a b c d e f g h) (In ts) p b c d e f g h) => In' Look_At_Head ts (Septenary a p : as) (a b c d e f g h) instance (Modify6 (a b c d e f g) (In ts) p b c d e f g) => In' Look_At_Head ts (Senary a p : as) (a b c d e f g) instance (Modify5 (a b c d e f) (In ts) p b c d e f) => In' Look_At_Head ts (Quinary a p : as) (a b c d e f) instance (Modify4 (a b c d e) (In ts) p b c d e) => In' Look_At_Head ts (Quaternary a p : as) (a b c d e) instance (Modify3 (a b c d) (In ts) p b c d) => In' Look_At_Head ts (Ternary a p : as) (a b c d) instance (Modify2 (a b c) (In ts) p b c) => In' Look_At_Head ts (Binary a p : as) (a b c) instance (Modify (a b) (In ts) p b) => In' Look_At_Head ts (Unary a p : as) (a b) instance (p a) => In' Look_At_Head ts (AnyType p : as) a instance In' Look_At_Head ts (Type a : as) a instance In' (Where as as a) as as a => In as a instance (p a b c d e f g h i, q j) => (>|||||||||<) p q a b c d e f g h i j instance (p a b c d e f g h, q i) => (>||||||||<) p q a b c d e f g h i instance (p a b c d e f g, q h) => (>|||||||<) p q a b c d e f g h instance (p a b c d e f, q g) => (>||||||<) p q a b c d e f g instance (p a b c d e, q f) => (>|||||<) p q a b c d e f instance (p a b c d, q e) => (>||||<) p q a b c d e instance (p a b c, q d) => (>|||<) p q a b c d instance (p a b, q c) => (>||<) p q a b c instance (p a, q b) => (>|<) p q a b instance (p a b c d e f g h i j, q a b c d e f g h i j) => (>++++++++++<) p q a b c d e f g h i j instance (p a b c d e f g h i, q a b c d e f g h i) => (>+++++++++<) p q a b c d e f g h i instance (p a b c d e f g h, q a b c d e f g h) => (>++++++++<) p q a b c d e f g h instance (p a b c d e f g, q a b c d e f g) => (>+++++++<) p q a b c d e f g instance (p a b c d e f, q a b c d e f) => (>++++++<) p q a b c d e f instance (p a b c d e, q a b c d e) => (>+++++<) p q a b c d e instance (p a b c d, q a b c d) => (>++++<) p q a b c d instance (p a b c, q a b c) => (>+++<) p q a b c instance (p a b, q a b) => (>++<) p q a b instance (p a, q a) => (>+<) p q a instance Pure a -- | Template haskell tools for clusses. -- -- Basic tools are in the module Type.Cluss. module Type.Cluss.TH -- | clussify converts a type class into a cluss, roughly speaking. -- For example, if the visible instances of Show were to be only -- Show Int, Show a => Show -- [a], and (Show a, Show b) => Show (a, -- b), the result of $(clussify ''Show) will -- be -- --
-- Show >|< In [Type Int, Unary [] Show, Binary (,) (Show >|< Show)] ---- -- (in fact, the result will be more verbose, using Show -- >|< Pure >++< Pure >|< -- Show instead of Show >|< -- Show). -- -- Due to the stage restriction of template haskell, clussify -- can't catch the instances defined in the module where the -- classify is written. -- -- Note that clussify neglects complicated instances that cannot -- be simply expressed with the combinators in the module -- Type.Cluss. -- -- You need some language extensions to use clussify. Basically, -- this language pragma will do. -- --
-- {-# LANGUAGE TemplateHaskell, ConstraintKinds #-}
--
clussify :: Name -> Q Type