|`E      !"#$%&'()*+,-./0123456789:;<=>?@ABCD(c) Yusuke Matsushita 2014 BSD3 Yusuke Matsushita  provisional  portable  Trustworthy&'(2346=HJKM& as is a cluss, where as) is a list of type patterns. Normally, as; is concrete and does not contain any type variables, like  [% (->) (E >|< ), ) F] a. When a satisfies In as a, you can use the method  ::  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. TClusses call for some language extensions. Basically, this language pragma will do. <{-# LANGUAGE DataKinds, FlexibleContexts, TypeOperators #-}  as f- is a tuple that contains values of the type f a , where a can be any type that satisfies In as aE. Each value corresponds to each type pattern, and the values in  as f3 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 ) a , And1 for & a p , And2 for % a p, ..., and And10 for  a p.  as a judges whether a type a belongs to a cluss  as", on some level. When not sure,  always returns G. For example, when as has & [] E and a is [b],  can't judge if b belongs to E since the instances of E is open, but it assumes that b belongs to E and returns G.  (Is a) b == (a ~ b)  C(p >||||||||< q) a b c d e f g h i j == (p a b c d e f g h i, q j) ?(p >||||||||< q) a b c d e f g h i == (p a b c d e f g h, q i) :(p >|||||||< q) a b c d e f g h == (p a b c d e f g, q h) 5(p >||||||< q) a b c d e f g == (p a b c d e f, q g) 0(p >|||||< q) a b c d e f == (p a b c d e, q f) +(p >||||< q) a b c d e == (p a b c d, q e)  &(p >|||< q) a b c d == (p a b c, q d)  !(p >||< q) a b c == (p a b, q c)  (p >|< q) a b == (p a, q b)  U(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)  P(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)  K(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)  D(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)  =(p >++++++< q) a b c d e f == (p a b c d e f, q a b c d e f)  6(p >+++++< q) a b c d e == (p a b c d e, q a b c d e)  /(p >++++< q) a b c d == (p a b c d, q a b c d)  ((p >+++< q) a b c == (p a b c, q a b c)  !(p >++< q) a b == (p a b, q a b)  (p >+< q) a == (p a, q a)  a' is equivalent to the empty constraint ().  Pure a == () ( creates a recursion. In other words,  will work as  as7 itself when used in the type list (first parameter) as of , combined with ), <|, &, %, ..., E, >+<, >++<, ..., >++++++++++<, >|<, >||<, ..., and >|||||||||<.  Note that  will not be expanded into  asE if the condition described above is not satisfied. For example,  in the parameter of ( will not be expanded because it causes infinite recursion. Internally, the expansion is executed by Modify, Modify2, ..., and Modify10. The instance of . itself cannot be created since the context G ~ H 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. 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 -> I. a <| p, with a being of the kind 6i -> i2 -> i3 -> i4 -> i5 -> i6 -> i7 -> i8 -> i9 -> k, and p of the kind 5i -> i2 -> i3 -> i4 -> i5 -> i6 -> i7 -> i8 -> i9 -> I. a <| p, with a being of the kind 0i -> i2 -> i3 -> i4 -> i5 -> i6 -> i7 -> i8 -> k, and p of the kind /i -> i2 -> i3 -> i4 -> i5 -> i6 -> i7 -> i8 -> I. 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 -> I. !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 -> I. "a <| p, with a being of the kind i -> i2 -> i3 -> i4 -> i5 -> k, and p of the kind i -> i2 -> i3 -> i4 -> i5 -> I. #a <| p, with a being of the kind i -> i2 -> i3 -> i4 -> k, and p of the kind i -> i2 -> i3 -> i4 -> I. $a <| p, with a being of the kind i -> i2 -> i3 -> k, and p of the kind i -> i2 -> i3 -> I. %a <| p, with a being of the kind  i -> i2 -> k, and p of the kind  i -> i2 -> I. &a <| p, with a being of the kind i -> k, and p of the kind i -> I. 'The empty type a <| p is a type pattern, where a is a type constructor, and pP is a type function to a constraint from the type variables for the constructor a. The type pattern [] <| E corresponds to  instance E a => C [a] where ... (where C. is a corresponding type class), for example. You can replace &, % , ..., and  with <|F, but you can sometimes save the effort of annotating kinds using &, % , ..., or  instead of <|, especially when using the  PolyKinds5 extension, because the kinds of the parameters in &, % , ..., and $ are restricted as described below. (The empty type ( p is a type pattern, where pD is a type function from a type to a constraint. The type pattern ( E basically corresponds to  instance E a => C a where ... (where C4 is a corresponding type class), for example, but (1 is much more useful in that it does not cause overlapping instances whereas C: is likely to, because cluss instances are prioritized. )The empty type ) a is a type pattern, where a is a type. The type pattern ) J corresponds to  instance C J where ... (where CL 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. KLMNOPQRSTUVWXYZ[\]^_`abcdefghij  !"#$%&'()klmnopqrstuvwxyz{|}*+,-./0123456789:;<=>?@ABC~Q  !"#$%&'()qrstuvwxyz{|}*+,-./0123456789:;<=>?@ABCD)('&%$#"!  *+,-./0123456789:;<=>?@ABCKLMNOPQRSTUVWXYZ[\]^_`abcdefghij  !"#$%&'()klmnop*+,-./0123456789:;<=>?@ABC~qrstuvwxyz{|}7               'prstuvwxyz{|}*+,-./01234789:;<=>?@A(c) Yusuke Matsushita 2014 BSD3 Yusuke Matsushita  provisional  portable NoneDDb converts a type class into a cluss, roughly speaking. For example, if the visible instances of E were to be only E J, E a => E [a], and (E a, E b) => E (a, b), the result of $(D ''E) will be  BShow >|< In [Type Int, Unary [] Show, Binary (,) (Show >|< Show)] 1(in fact, the result will be more verbose, using E >|< Pure >++< Pure >|< E instead of E >|< E). 2Due to the stage restriction of template haskell, D; can't catch the instances defined in the module where the classify is written.  Note that Dc neglects complicated instances that cannot be simply expressed with the combinators in the module  Type-Cluss.html Type.Cluss. )You need some language extensions to use D+. Basically, this language pragma will do. 2{-# LANGUAGE TemplateHaskell, ConstraintKinds #-} DDD D      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJHKLMNOMNPMQRMNSTUUVWXXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ cluss-0.2 Type.Cluss Type.Cluss.THAllOfFAllOfIInprojAllOf'AllOfHasIs >|||||||||< >||||||||< >|||||||<>||||||<>|||||<>||||<>|||<>||<>|< >++++++++++< >+++++++++< >++++++++< >+++++++<>++++++<>+++++<>++++<>+++<>++<>+<PureThisDenaryNonaryOctary SeptenarySenaryQuinary QuaternaryTernaryBinaryUnary<|AnyTypeTypeandIandI1andI2andI3andI4andI5andI6andI7andI8andI9andI10noneIprojIandFandF1andF2andF3andF4andF5andF6andF7andF8andF9andF10noneFprojFclussifybaseGHC.ShowShowGHC.BaseStringghc-prim GHC.TypesTrueFalseGHC.Prim ConstraintIntAllOfF'FuncunFuncAllOfI'IdunIdIn'proj'Check10Check9Check8Check7Check6Check5Check4Check3Check2CheckModify10Modify9Modify8Modify7Modify6Modify5Modify4Modify3Modify2ModifyHas'WhereNo_I_Don't_Have_That Look_At_Tail Look_At_HeadIf&&$NoneAnd10And9And8And7And6And5And4And3And2And1AndAnyAnd$fIn'kLook_At_Tailts:a$fIn'kLook_At_Tailts:a0$fIn'kLook_At_Tailts:a1$fIn'kLook_At_Tailts:a2$fIn'kLook_At_Tailts:a3$fIn'kLook_At_Tailts:a4$fIn'kLook_At_Tailts:a5$fIn'kLook_At_Tailts:a6$fIn'kLook_At_Tailts:a7$fIn'kLook_At_Tailts:a8$fIn'kLook_At_Tailts:a9$fIn'kLook_At_Tailts:a10$fIn'kLook_At_Headts:a$fIn'kLook_At_Headts:a0$fIn'kLook_At_Headts:a1$fIn'kLook_At_Headts:a2$fIn'kLook_At_Headts:a3$fIn'kLook_At_Headts:a4$fIn'kLook_At_Headts:a5$fIn'kLook_At_Headts:a6$fIn'kLook_At_Headts:a7$fIn'kLook_At_Headts:a8$fIn'kLook_At_Headts:a9$fIn'kLook_At_Headts:a10$fInkasaTFCo:R:AllOf'kts[]tTFCo:R:AllOf'kts:tTFCo:R:AllOf'kts:t0TFCo:R:AllOf'kts:t1TFCo:R:AllOf'kts:t2TFCo:R:AllOf'kts:t3TFCo:R:AllOf'kts:t4TFCo:R:AllOf'kts:t5TFCo:R:AllOf'kts:t6TFCo:R:AllOf'kts:t7TFCo:R:AllOf'kts:t8TFCo:R:AllOf'kts:t9TFCo:R:AllOf'kts:t10TFCo:R:Has'No_I_Don't_Have_ThatTFCo:R:Has'Look_At_TailTFCo:R:Has'Look_At_HeadTFCo:R:Haskasa#$f>|||||||||||||||||||||||||||||||||||||||||||||+++++++++++++++++++++++++++++++++++++++++++++++++++++++