!OiP      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~       !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO(c) 2019 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela <rudy@matela.com.br>Safe[express O(n log n)0. Sorts and remove repetitions. Equivalent to  nub . sort. s> nubSort [1,2,3] [1,2,3] > nubSort [3,2,1] [1,2,3] > nubSort [3,2,1,3,2,1] [1,2,3] > nubSort [3,3,1,1,2,2] [1,2,3]express O(n log n)I. Checks that all elements of the first list are elements of the second.express O(n log n)I. Checks that all elements of the first list are elements of the second.express O(n log n)_. Checks that all elements are unique. This function is a faster equivalent to the following: isNub xs = nub xs == xs Examples: EisNub [] = True isNub [1,2,3] = True isNub [2,1,2] = FalseexpressO(n). Like P0 but returns the key itself if nothing is found. > lookupId 5 [(1,2),(3,4)] 5 "> lookupId 5 [(1,2),(3,4),(5,6)] 6|QRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~P5(c) 2016-2019 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela <rudy@matela.com.br>Safe4expressCUnquotes a string if possible, otherwise, this is just an identity. K> unquote "\"string\"" "string" > unquote "something else" "something else"express8Checks if a string-encoded Haskell expression is atomic. z> atomic "123" True > atomic "42 + 1337" False > atomic "'a'" True > atomic "[1,2,3,4,5]" True > atomic "(1,2,3,4,5)" True>FIXME: The current implementation may produce false positives: a> atomic "'a' < 'b'" True > atomic "\"asdf\" ++ \"qwer\"" True > atomic "[1,2,3] ++ [4,5,6]" True7but this does not cause problems for (all?) most cases. express'Check if a function / operator is infix aisInfix "foo" == False isInfix "(+)" == False isInfix "`foo`" == True isInfix "+" == True express3Returns the precedence of default Haskell operatorsexpressIs the string of the form `string`express3Transform an infix operator into an infix function: 3toPrefix "`foo`" == "foo" toPrefix "+" == "(+)"expressGReturns an infinite list of variable names based on the given template. @> variableNamesFromTemplate "x" ["x", "y", "z", "x'", "y'", ...] @> variableNamesFromTemplate "p" ["p", "q", "r", "p'", "q'", ...] H> variableNamesFromTemplate "xy" ["xy", "zw", "xy'", "zw'", "xy''", ...]Qnopq    (c) 2019 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela <rudy@matela.com.br>SafefexpressDIf we were to come up with a variable name for the given type what  would it be?An instance for a given type  Ty  is simply given by: #instance Name Ty where name _ = "x" Examples: > name (undefined :: Int) "x" > name (undefined :: Bool) "p"  > name (undefined :: [Int]) "xs";This is then used to generate an infinite list of variable : V> names (undefined :: Int) ["x", "y", "z", "x'", "y'", "z'", "x''", "y''", "z''", ...] W> names (undefined :: Bool) ["p", "q", "r", "p'", "q'", "r'", "p''", "q''", "r''", ...] Y> names (undefined :: [Int]) ["xs", "ys", "zs", "xs'", "ys'", "zs'", "xs''", "ys''", ...]expressO(1).;Returns a name for a variable of the given argument's type. > name (undefined :: Int) "x" !> name (undefined :: [Bool]) "ps" +> name (undefined :: [Maybe Integer]) "mxs"The default definition is:  name _ = "x"expressOReturns na infinite list of variable names from the given type: the result of  after . V> names (undefined :: Int) ["x", "y", "z", "x'", "y'", "z'", "x''", "y''", "z''", ...] W> names (undefined :: Bool) ["p", "q", "r", "p'", "q'", "r'", "p''", "q''", "r''", ...] Y> names (undefined :: [Int]) ["xs", "ys", "zs", "xs'", "ys'", "zs'", "xs''", "ys''", ...]express xnames (undefined :: [Int]) = ["xs", "ys", "zs", "xs'", ...] names (undefined :: [Bool]) = ["ps", "qs", "rs", "ps'", ...]express rnames (undefined :: ((),(),(),())) = ["uuuu", "uuuu1", ...] names (undefined :: (Int,Int,Int,Int)) = ["xxxx", ...] express snames (undefined :: (Int,Int,Int)) = ["xyz","uvw", ...] names (undefined :: (Int,Bool,Char)) = ["xpc", "xpc1", ...]!express unames (undefined :: (Int,Int)) = ["xy", "zw", "xy'", ...] names (undefined :: (Bool,Bool)) = ["pq", "rs", "pq'", ...]"express vnames (undefined :: Either Int Int) = ["exy", "exy1", ...] names (undefined :: Either Int Bool) = ["exp", "exp1", ...]#express vnames (undefined :: Maybe Int) = ["mx", "mx1", "mx2", ...] nemes (undefined :: Maybe Bool) = ["mp", "mp1", "mp2", ...]$express mnames (undefined :: ()->()) = ["f", "g", "h", "f'", ...] names (undefined :: Int->Int) = ["f", "g", "h", ...]%express Yname (undefined :: Double) = "x" names (undefined :: Double) = ["x", "y", "z", "x'", ...]&express Wname (undefined :: Float) = "x" names (undefined :: Float) = ["x", "y", "z", "x'", ...]'express ]name (undefined :: Rational) = "q" names (undefined :: Rational) = ["q", "r", "s", "q'", ...](express ]name (undefined :: Ordering) = "o" names (undefined :: Ordering) = ["o", "p", "q", "o'", ...])express [name (undefined :: Char) = "c" names (undefined :: Char) = ["c", "d", "e", "c'", "d'", ...]*express [name (undefined :: Integer) = "x" names (undefined :: Integer) = ["x", "y", "z", "x'", ...]+express Yname (undefined :: Int) = "x" names (undefined :: Int) = ["x", "y", "z", "x'", "y'", ...],express [name (undefined :: Bool) = "p" names (undefined :: Bool) = ["p", "q", "r", "p'", "q'", ...]-express Wname (undefined :: ()) = "u" names (undefined :: ()) = ["u", "v", "w", "u'", "v'", ...](c) 2019 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela <rudy@matela.com.br>Nonem9expressgGiven a type name, return the number of arguments taken by that type. Examples in partially broken TH: arity ''Int === Q 0 arity ''Int->Int === Q 0 arity ''Maybe === Q 1 arity ''Either === Q 2 arity ''Int-> === Q 1ZThis works for Data's and Newtype's and it is useful when generating typeclass instances.      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~./0123456789:;<=>?@ABC1./23456789:;<?@C0B=>A(c) 2019 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela <rudy@matela.com.br>NoneCDexpress Derives a  instance for the given type  .This function needs the TemplateHaskell extension.EexpressSame as D4 but does not warn when instance already exists (D is preferable).Fexpress Derives a  instance for a given type  3 cascading derivation of type arguments as well.DEFDFE(c) 2016-2019 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela <rudy@matela.com.br>SafesMexpresspThis function returns the type of the element of a list. It will throw an error when not given the list type. > > elementTy $ typeOf (undefined :: [Int]) Int > > elementTy $ typeOf (undefined :: [[Int]]) [Int] > > elementTy $ typeOf (undefined :: [Bool]) Bool > > elementTy $ typeOf (undefined :: Bool) *** Exception: error (elementTy): `Bool' is not a list typeUexpressO(n)9. Return all sub types of a given type including itself. +> typesIn $ typeOf (undefined :: Int) [Int] -> typesIn $ typeOf (undefined :: Bool) [Bool] 7> typesIn $ typeOf (undefined :: [Int]) [ Int , [Int] ] \> typesIn $ typeOf (undefined :: Int -> Int -> Int) [ Int , Int -> Int , Int -> Int -> Int ] p> typesIn $ typeOf (undefined :: Int -> [Int] -> [Int]) [ Int , [Int] , [Int] -> [Int] , Int -> [Int] -> [Int] ] B> typesIn $ typeOf (undefined :: Maybe Bool) [ Bool , Maybe Bool ]WexpressAn infix alias for . It is right associative.5GHIJKLMNOPQRSTUVWHJRKLINOPSTQGMUVWW9 (c) 2019 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela <rudy@matela.com.br>Safe2'XexpressValues of type X represent objects or applications between objects. Each object is encapsulated together with its type and string representation. Values encoded in Xs are always monomorphic.An X can be constructed using:\, for values that are  instances;[, for values that are not  instances, like functions;Z, for applications between Xs. > val False False :: Bool 0> value "not" not :$ val False not False :: BoolAn X can be evaluated using d, e or f. > evl $ val (1 :: Int) :: Int 1 1> evaluate $ val (1 :: Int) :: Maybe Bool Nothing > eval 'a' (val 'b') 'b'ing a value of type XW will return a pretty-printed representation of the expression together with its type. 9> show (value "not" not :$ val False) "not False :: Bool"X is like 2 but has support for applications and variables (Z, ^).The ^ underscore convention: Functions that manipulate X)s usually follow the convention where a [ whose  representation starts with '_' represents a ^iable.Yexpressa [ enconded as  and Zexpress(function application between expressions[expressO(1)J. It takes a string representation of a value and a value, returning an X- with that terminal value. For instances of , it is preferable to use \. '> value "0" (0 :: Integer) 0 :: Integer > value "'a'" 'a' 'a' :: Char  > value "True" True True :: Bool 0> value "id" (id :: Int -> Int) id :: Int -> Int A> value "(+)" ((+) :: Int -> Int -> Int) (+) :: Int -> Int -> Int B> value "sort" (sort :: [Bool] -> [Bool]) sort :: [Bool] -> [Bool]\expressO(1). A shorthand for [ for values that are  instances. > val (0 :: Int) 0 :: Int > val 'a' 'a' :: Char > val True True :: BoolExample equivalences to [: Tval 0 = value "0" 0 val 'a' = value "'a'" 'a' val True = value "True" True]expressO(n). Creates an X' representing a function application.  an X! application if the types match,  otherwise. (cf. Z) :> value "id" (id :: () -> ()) $$ val () Just (id () :: ()) M> value "abs" (abs :: Int -> Int) $$ val (1337 :: Int) Just (abs 1337 :: Int) 4> value "abs" (abs :: Int -> Int) $$ val 'a' Nothing 3> value "abs" (abs :: Int -> Int) $$ val () Nothing^expressO(1). Creates an X@ representing a variable with the given name and argument type. %> var "x" (undefined :: Int) x :: Int #> var "u" (undefined :: ()) u :: () +> var "xs" (undefined :: [Int]) xs :: [Int]This function follows the underscore convention: a variable is just a [6 whose string representation starts with underscore ('_')._expressO(n)}. Computes the type of an expression. This raises errors, but this should not happen if expressions are smart-constructed. [> let one = val (1 :: Int) > let bee = val 'b' > let absE = value "abs" (abs :: Int -> Int)  > typ one Int > typ bee Char > typ absE Int -> Int > typ (absE :$ one) Int U> typ (absE :$ bee) *** Exception: type mismatch, cannot apply `Int -> Int' to `Char' ^> typ ((absE :$ bee) :$ one) *** Exception: type mismatch, cannot apply `Int -> Int' to `Char'`expressO(n). Computes the type of an expression returning either the type of the given expression when possible or when there is a type error, the pair of types which produced the error. [> let one = val (1 :: Int) > let bee = val 'b' > let absE = value "abs" (abs :: Int -> Int) > etyp one Right Int > etyp bee Right Char > etyp absE Right (Int -> Int) > etyp (absE :$ one) Right Int ,> etyp (absE :$ bee) Left (Int -> Int, Char) 5> etyp ((absE :$ bee) :$ one) Left (Int -> Int, Char)aexpressO(n) . Returns  the type of an expression or  when there is an error. [> let one = val (1 :: Int) > let bee = val 'b' > let absE = value "abs" (abs :: Int -> Int) > mtyp one Just Int > mtyp (absE :$ bee) NothingbexpressO(n). Returns whether the given X is ill typed. (cf. c) [> let one = val (1 :: Int) > let bee = val 'b' > let absE = value "abs" (abs :: Int -> Int) +> isIllTyped (absE :$ val (1 :: Int)) False #> isIllTyped (absE :$ val 'b') TruecexpressO(n). Returns whether the given X is well typed. (cf. b) +> isWellTyped (absE :$ val (1 :: Int)) True %> isWellTyped (absE :$ val 'b') FalsedexpressO(n). ; the value of an expression when possible (correct type), - otherwise. This does not catch errors from   [s. d> let one = val (1 :: Int) > let bee = val 'b' > let negateE = value "negate" (negate :: Int -> Int) "> evaluate one :: Maybe Int Just 1 $> evaluate one :: Maybe Char Nothing #> evaluate bee :: Maybe Int Nothing %> evaluate bee :: Maybe Char Just 'b' 2> evaluate $ negateE :$ one :: Maybe Int Just (-1) 0> evaluate $ negateE :$ bee :: Maybe Int NothingeexpressO(n)]. Evaluates an expression when possible (correct type). Returns a default value otherwise. v> let two = val (2 :: Int) > let three = val (3 :: Int) > let e1 -+- e2 = value "+" ((+) :: Int->Int->Int) :$ e1 :$ e2 !> eval 0 $ two -+- three :: Int 5 &> eval 'z' $ two -+- three :: Char 'z' #> eval 0 $ two -+- val '3' :: Int 0fexpressO(n)T. Evaluates an expression when possible (correct type). Raises an error otherwise. > evl $ two -+- three :: Int 5 f> evl $ two -+- three :: Bool *** Exception: evl: cannot evaluate Expr `2 + 3 :: Int' at the Bool type-This may raise errors, please consider using e or d.gexpressO(n)). Evaluates an expression to a terminal  value when possible. Returns  otherwise. <> toDynamic $ val (123 :: Int) :: Maybe Dynamic Just <<Int>> M> toDynamic $ value "abs" (abs :: Int -> Int) :$ val (-1 :: Int) Just <<Int>> @> toDynamic $ value "abs" (abs :: Int -> Int) :$ val 'a' NothingjexpressO(n)G. Returns a string representation of an expression. Differently from  (:: Expr -> String9) this function does not include the type in the output. )> putStrLn $ showExpr (one -+- two) 1 + 2 W> putStrLn $ showExpr $ (pp -||- true) -&&- (qq -||- false) (p || True) && (q || False)kexpressO(n)". Compares the complexity of two Xs. An expression e1 is strictly simpler than another expression e2I if the first of the following conditions to distingish between them is: e1 is smaller in size/length than e2 , e.g.: x + y < x + (y + z);or, e1" has more distinct variables than e2 , e.g.:  x + y < x + x;or, e1$ has more variable occurrences than e2 , e.g.:  x + x < 1 + x;or, e1# has fewer distinct constants than e2 , e.g.:  1 + 1 < 0 + 1.9They're otherwise considered of equal complexity, e.g.: x + y and y + z. 9> (xx -+- yy) `compareComplexity` (xx -+- (yy -+- zz)) LT 0> (xx -+- yy) `compareComplexity` (xx -+- xx) LT 1> (xx -+- xx) `compareComplexity` (one -+- xx) LT 5> (one -+- one) `compareComplexity` (zero -+- one) LT 0> (xx -+- yy) `compareComplexity` (yy -+- zz) EQ 6> (zero -+- one) `compareComplexity` (one -+- zero) EQlexpressO(n)!. Unfold a function application X( into a list of function and arguments. unfoldApp $ e0 = [e0] unfoldApp $ e0 :$ e1 = [e0,e1] unfoldApp $ e0 :$ e1 :$ e2 = [e0,e1,e2] unfoldApp $ e0 :$ e1 :$ e2 :$ e3 = [e0,e1,e2,e3] Remember Z is left-associative, so: unfoldApp e0 = [e0] unfoldApp (e0 :$ e1) = [e0,e1] unfoldApp ((e0 :$ e1) :$ e2) = [e0,e1,e2] unfoldApp (((e0 :$ e1) :$ e2) :$ e3) = [e0,e1,e2,e3]expressO(n). Unfold a tuple X into a list of values. F> let pair' a b = value "," ((,) :: Bool->Char->(Bool,Char)) :$ a :$ b 6> pair' (val True) (val 'a') (True,'a') :: (Bool,Char) E> unfoldTuple $ pair' (val True) (val 'a') [True :: Bool,'a' :: Char] X> let trio' a b c = value ",," ((,,) :: Bool->Char->Int->(Bool,Char,Int)) :$ a :$ b :$ c O> trio' (val False) (val 'b') (val (9 :: Int)) (False,'b',9) :: (Bool,Char,Int) a> unfoldTuple $ trio' (val False) (val 'b') (val (9 :: Int)) [False :: Bool,'b' :: Char,9 :: Int]dNOTE: this function returns an empty list when the representation of the tupling function is (,), (,,), (,,,) or (,,,...)+. This is intentional, allowing the  X instance to present (,) 1 2 differently than (1,2).mexpressO(n). Check if an X3 has a variable. (By convention, any value whose  representation starts with '_'.) ,> hasVar $ value "not" not :$ val True False J> hasVar $ value "&&" (&&) :$ var "p" (undefined :: Bool) :$ val True TruenexpressO(n). Returns whether a X has no$ variables. This is equivalent to " not . hasVar".,The name "ground" comes from term rewriting. -> isGround $ value "not" not :$ val True True M> isGround $ value "&&" (&&) :$ var "p" (undefined :: Bool) :$ val True FalseoexpressO(1). Returns whether an X is a terminal constant. (cf. n). ,> isConst $ var "x" (undefined :: Int) False > isConst $ val False True .> isConst $ value "not" not :$ val False FalsepexpressO(1). Returns whether an X is a terminal variable (^ ). (cf. m). )> isVar $ var "x" (undefined :: Int) True > isVar $ val False False >> isVar $ value "not" not :$ var "p" (undefined :: Bool) FalseqexpressO(1). Returns whether an X is a terminal value (Y). +> isValue $ var "x" (undefined :: Int) True > isValue $ val False True @> isValue $ value "not" not :$ var "p" (undefined :: Bool) False+This is equivalent to pattern matching the Y constructor. Properties:  isValue (Value e) = True  isValue (e1 :$ e2) = False  isValue = not . isApp # isValue e = isVar e || isConst erexpressO(1). Returns whether an X is an application (Z). *> isApp $ var "x" (undefined :: Int) False > isApp $ val False False >> isApp $ value "not" not :$ var "p" (undefined :: Bool) True +This is equivalent to pattern matching the Z constructor. Properties:  isApp (e1 :$ e2) = True  isApp (Value e) = False  isApp = not . isValue - isApp e = not (isVar e) && not (isConst e)sexpressO(n) for the spine, O(n^2) for full evaluation. Lists subexpressions of a given expression in order and with repetitions. This includes the expression itself and partial function applications. (cf. t) n> subexprs (xx -+- yy) [ x + y :: Int , (x +) :: Int -> Int , (+) :: Int -> Int -> Int , x :: Int , y :: Int ] > subexprs (pp -&&- (pp -&&- true)) [ p && (p && True) :: Bool , (p &&) :: Bool -> Bool , (&&) :: Bool -> Bool -> Bool , p :: Bool , p && True :: Bool , (p &&) :: Bool -> Bool , (&&) :: Bool -> Bool -> Bool , p :: Bool , True :: Bool ]texpress O(n log n) for the spine, O(n^2) for full evaluation. Lists all subexpressions of a given expression without repetitions. This includes the expression itself and partial function applications. (cf. s) q> nubSubexprs (xx -+- yy) [ x :: Int , y :: Int , (+) :: Int -> Int -> Int , (x +) :: Int -> Int , x + y :: Int ] > nubSubexprs (pp -&&- (pp -&&- true)) [ p :: Bool , True :: Bool , (&&) :: Bool -> Bool -> Bool , (p &&) :: Bool -> Bool , p && True :: Bool , p && (p && True) :: Bool ]uexpressO(n)S. Lists all terminal values in an expression in order and with repetitions. (cf. v) G> values (xx -+- yy) [ (+) :: Int -> Int -> Int , x :: Int , y :: Int ] v> values (xx -+- (yy -+- zz)) [ (+) :: Int -> Int -> Int , x :: Int , (+) :: Int -> Int -> Int , y :: Int , z :: Int ] z> values (zero -+- (one -*- two)) [ (+) :: Int -> Int -> Int , 0 :: Int , (*) :: Int -> Int -> Int , 1 :: Int , 2 :: Int ] S> values (pp -&&- true) [ (&&) :: Bool -> Bool -> Bool , p :: Bool , True :: Bool ]vexpress O(n log n)I. Lists all terminal values in an expression without repetitions. (cf. u) H> nubValues (xx -+- yy) [ x :: Int , y :: Int , (+) :: Int -> Int -> Int] ^> nubValues (xx -+- (yy -+- zz)) [ x :: Int , y :: Int , z :: Int , (+) :: Int -> Int -> Int ] }> nubValues (zero -+- (one -*- two)) [ 0 :: Int , 1 :: Int , 2 :: Int , (*) :: Int -> Int -> Int , (+) :: Int -> Int -> Int ] E> nubValues (pp -&&- pp) [ p :: Bool , (&&) :: Bool -> Bool -> Bool ]wexpressO(n)Q. List terminal constants in an expression in order and with repetitions. (cf. x) 1> consts (xx -+- yy) [ (+) :: Int -> Int -> Int ] U> consts (xx -+- (yy -+- zz)) [ (+) :: Int -> Int -> Int , (+) :: Int -> Int -> Int ] z> consts (zero -+- (one -*- two)) [ (+) :: Int -> Int -> Int , 0 :: Int , (*) :: Int -> Int -> Int , 1 :: Int , 2 :: Int ] G> consts (pp -&&- true) [ (&&) :: Bool -> Bool -> Bool , True :: Bool ]xexpress O(n log n)G. List terminal constants in an expression without repetitions. (cf. w) 4> nubConsts (xx -+- yy) [ (+) :: Int -> Int -> Int ] => nubConsts (xx -+- (yy -+- zz)) [ (+) :: Int -> Int -> Int ] J> nubConsts (pp -&&- true) [ True :: Bool , (&&) :: Bool -> Bool -> Bool ]yexpressO(n)M. Lists all variables in an expression in order and with repetitions. (cf. z) *> vars (xx -+- yy) [ x :: Int , y :: Int ] >> vars (xx -+- (yy -+- xx)) [ x :: Int , y :: Int , x :: Int ] "> vars (zero -+- (one -*- two)) [] !> vars (pp -&&- true) [p :: Bool]zexpress O(n log n)C. Lists all variables in an expression without repetitions. (cf. y) -> nubVars (yy -+- xx) [ x :: Int , y :: Int ] 6> nubVars (xx -+- (yy -+- xx)) [ x :: Int , y :: Int ] %> nubVars (zero -+- (one -*- two)) [] $> nubVars (pp -&&- true) [p :: Bool]{expressO(n)_. Return the arity of the given expression, i.e. the number of arguments that its type takes. > arity (val (0::Int)) 0 > arity (val False) 0 )> arity (value "id" (id :: Int -> Int)) 1 6> arity (value "const" (const :: Int -> Int -> Int)) 2 > arity (one -+- two) 0|expressO(n)W. Returns the size of the given expression, i.e. the number of terminal values in it. zero = val (0 :: Int) one = val (1 :: Int) two = val (2 :: Int) xx -+- yy = value "+" ((+) :: Int->Int->Int) :$ xx :$ yy abs' xx = value "abs" (abs :: Int->Int) :$ xx  > size zero 1 > size (one -+- two) 3 > size (abs' one) 2}expressO(n). Returns the maximum depth of a given expression given by the maximum number of nested function applications. Curried function application is counted  only oncel, i.e. the application of a two argument function increases the depth of both its arguments by one. (cf. ~)With zero = val (0 :: Int) one = val (1 :: Int) two = val (2 :: Int) xx -+- yy = value "+" ((+) :: Int->Int->Int) :$ xx :$ yy abs' xx = value "abs" (abs :: Int->Int) :$ xx > depth zero 1 > depth (one -+- two) 2 > depth (abs' one -+- two) 3VFlipping arguments of applications in any of the subterms does not affect the result.~expressO(n). Returns the maximum height of a given expression given by the maximum number of nested function applications. Curried function application is counted  each time, i.e. the application of a two argument function increases the depth of its first argument by two and of its second argument by one. (cf. })With: zero = val (0 :: Int) one = val (1 :: Int) two = val (2 :: Int) const' xx yy = value "const" (const :: Int->Int->Int) :$ xx :$ yy abs' xx = value "abs" (abs :: Int->Int) :$ xxThen: > height zero 1 > height (abs' one) 2 > height ((const' one) two) 3 $> height ((const' (abs' one)) two) 4 $> height ((const' one) (abs' two)) 3VFlipping arguments of applications in subterms may change the result of the function.expressO(n)q. Does not evaluate values when comparing, but rather uses their representation as strings and their types..This instance works for ill-typed expressions.'XYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'XYZ[\]^def_`agqrpobcmnk{|}~suywtvzxljhi(c) 2019 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela <rudy@matela.com.br>Safe>expressO(n*m)E. Applies a function to all terminal values in an expression. (cf. ) Given that: > let zero = val (0 :: Int) > let one = val (1 :: Int) > let two = val (2 :: Int) > let three = val (3 :: Int) > let xx -+- yy = value "+" ((+) :: Int->Int->Int) :$ xx :$ yy > let intToZero e = if typ e == typ zero then zero else eThen: ,> one -+- (two -+- three) 1 + (2 + 3) :: Int F> mapValues intToZero $ one -+- (two -+- three) 0 + (0 + 0) :: Integer$Given that the argument function is O(m), this function is O(n*m).expressO(n*m)8. Applies a function to all variables in an expression. Given that: > let primeify e = if isVar e | then case e of (Value n d) -> Value (n ++ "'") d | else e > let xx = var "x" (undefined :: Int) > let yy = var "y" (undefined :: Int) > let xx -+- yy = value "+" ((+) :: Int->Int->Int) :$ xx :$ yyThen: > xx -+- yy x + y :: Int > primeify xx x' :: Int -> mapVars primeify $ xx -+- yy x' + y' :: Int <> mapVars (primeify . primeify) $ xx -+- yy x'' + y'' :: Int$Given that the argument function is O(m), this function is O(n*m).expressO(n*m)A. Applies a function to all terminal constants in an expression. Given that: > let one = val (1 :: Int) > let two = val (2 :: Int) > let xx -+- yy = value "+" ((+) :: Int->Int->Int) :$ xx :$ yy > let intToZero e = if typ e == typ zero then zero else eThen: )> one -+- (two -+- xx) 1 + (2 + x) :: Int C> mapConsts intToZero (one -+- (two -+- xx)) 0 + (0 + x) :: Integer$Given that the argument function is O(m), this function is O(n*m).expressO(n*m). Substitute subexpressions of an expression using the given function. Outer expressions have more precedence than inner expressions. (cf. )With: > let xx = var "x" (undefined :: Int) > let yy = var "y" (undefined :: Int) > let zz = var "z" (undefined :: Int) > let plus = value "+" ((+) :: Int->Int->Int) > let times = value "*" ((*) :: Int->Int->Int) > let xx -+- yy = plus :$ xx :$ yy > let xx -*- yy = times :$ xx :$ yy t> let pluswap (o :$ xx :$ yy) | o == plus = Just $ o :$ yy :$ xx | pluswap _ = NothingThen: H> mapSubexprs pluswap $ (xx -*- yy) -+- (yy -*- zz) y * z + x * y :: Int L> mapSubexprs pluswap $ (xx -+- yy) -*- (yy -+- zz) (y + x) * (z + y) :: IntqSubstitutions do not stack, in other words a replaced expression or its subexpressions are not further replaced: L> mapSubexprs pluswap $ (xx -+- yy) -+- (yy -+- zz) (y + z) + (x + y) :: Int$Given that the argument function is O(m), this function is O(n*m).expressO(n*m)b. Substitute occurrences of values in an expression from the given list of substitutions. (cf. ) Given that: > let xx = var "x" (undefined :: Int) > let yy = var "y" (undefined :: Int) > let zz = var "z" (undefined :: Int) > let xx -+- yy = value "+" ((+) :: Int->Int->Int) :$ xx :$ yyThen: Q> ((xx -+- yy) -+- (yy -+- zz)) //- [(xx, yy), (zz, yy)] (y + y) + (y + y) :: Int Z> ((xx -+- yy) -+- (yy -+- zz)) //- [(yy, yy -+- zz)] (x + (y + z)) + ((y + z) + z) :: IntIThis function does not work for substituting non-terminal subexpressions: 0> (xx -+- yy) //- [(xx -+- yy, zz)] x + y :: IntPlease use the slower + if you want the above replacement to work.Replacement happens only once: $> xx //- [(xx,yy), (yy,zz)] y :: Int(Given that the argument list has length m, this function is O(n*m).expressO(n*n*m)[. Substitute subexpressions in an expression from the given list of substitutions. (cf. ).Please consider using < if you are replacing just terminal values as it is faster. Given that: > let xx = var "x" (undefined :: Int) > let yy = var "y" (undefined :: Int) > let zz = var "z" (undefined :: Int) > let xx -+- yy = value "+" ((+) :: Int->Int->Int) :$ xx :$ yyThen: R> ((xx -+- yy) -+- (yy -+- zz)) // [(xx -+- yy, yy), (yy -+- zz, yy)] y + y :: Int O> ((xx -+- yy) -+- zz) // [(xx -+- yy, zz), (zz, xx -+- yy)] z + (x + y) :: IntdReplacement happens only once with outer expressions having more precedence than inner expressions. <> (xx -+- yy) // [(yy,xx), (xx -+- yy,zz), (zz,xx)] z :: Int(Given that the argument list has length m, this function is O(n*n*m). Remember that since n= is the size of an expression, comparing two expressions is O(n)5 in the worst case, and we may need to compare with n" subexpressions in the worst case.expressRename variables in an X. 2> renameVarsBy (++ "'") (xx -+- yy) x' + y' :: Int D> renameVarsBy (++ "'") (yy -+- (zz -+- xx)) (y' + (z' + x')) :: Int /> renameVarsBy (++ "1") (abs' xx) abs x1 :: Int ?> renameVarsBy (++ "2") $ abs' (xx -+- yy) abs (x2 + y2) :: IntNOTE: this will affect holes! (c) 2019 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela <rudy@matela.com.br>SafeCexpressO(1) . Creates a ^&iable with the same type as the given X. 9> let one = val (1::Int) > "x" `varAsTypeOf` one x :: Int '> "p" `varAsTypeOf` val False p :: BoolexpressO(1). Creates an X7 representing a typed hole with the type of the given X. (cf. ) >> val (1::Int) 1 :: Int > holeAsTypeOf $ val (1::Int) _ :: IntexpressO(1). Creates an X6 representing a typed hole of the given argument type. "> hole (undefined :: Int) _ :: Int 4> hole (undefined :: Maybe String) _ :: Maybe [Char]CA hole is represented as a variable with no name or a value named "_": &hole x = var "" x hole x = value "_" xexpressO(1). Checks if an X represents a typed hole. (cf. ) '> isHole $ hole (undefined :: Int) True ,> isHole $ value "not" not :$ val True False > isHole $ val 'a' FalseexpressO(n)J. Lists all holes in an expression, in order and with repetitions. (cf. ) .> holes $ hole (undefined :: Bool) [_ :: Bool] g> holes $ value "&&" (&&) :$ hole (undefined :: Bool) :$ hole (undefined :: Bool) [_ :: Bool,_ :: Bool] `> holes $ hole (undefined :: Bool->Bool) :$ hole (undefined::Bool) [_ :: Bool -> Bool,_ :: Bool]express O(n log n)?. Lists all holes in an expression without repetitions. (cf. ) 1> nubHoles $ hole (undefined :: Bool) [_ :: Bool] `> nubHoles $ value "&&" (&&) :$ hole (undefined :: Bool) :$ hole (undefined :: Bool) [_ :: Bool] c> nubHoles $ hole (undefined :: Bool->Bool) :$ hole (undefined::Bool) [_ :: Bool,_ :: Bool -> Bool]expressTGenerate an infinite list of variables based on a template and a given type. (cf. ) > putL 10 $ listVars "x" (undefined :: Int) [ x :: Int , y :: Int , z :: Int , x' :: Int , y' :: Int , z' :: Int , x'' :: Int , ... ] > putL 10 $ listVars "p" (undefined :: Bool) [ p :: Bool , q :: Bool , r :: Bool , p' :: Bool , q' :: Bool , r' :: Bool , p'' :: Bool , ... ]expressUGenerate an infinite list of variables based on a template and the type of a given X. (cf. ) t> let one = val (1::Int) > putL 10 $ "x" `listVarsAsTypeOf` one [ x :: Int , y :: Int , z :: Int , x' :: Int , ... ] y> let false = val False > putL 10 $ "p" `listVarsAsTypeOf` false [ p :: Bool , q :: Bool , r :: Bool , p' :: Bool , ... ] (c) 2019 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela <rudy@matela.com.br>Safe2texpressO(n). Folds a list of X with function application (Z ). This reverses the effect of l. foldApp [e0] = e0 foldApp [e0,e1] = e0 :$ e1 foldApp [e0,e1,e2] = e0 :$ e1 :$ e2 foldApp [e0,e1,e2,e3] = e0 :$ e1 :$ e2 :$ e3 Remember Z is left-associative, so: foldApp [e0] = e0 foldApp [e0,e1] = (e0 :$ e1) foldApp [e0,e1,e2] = ((e0 :$ e1) :$ e2) foldApp [e0,e1,e2,e3] = (((e0 :$ e1) :$ e2) :$ e3)This function may! produce an ill-typed expression.expressO(1). Folds a pair of X values into a single X. (cf. )This always# generates an ill-typed expression. O> foldPair (val False, val (1::Int)) (False,1) :: ill-typed # ExprPair $ Bool # L> foldPair (val (0::Int), val True) (0,True) :: ill-typed # ExprPair $ Int #9This is useful when applying transformations on pairs of X s, such as ,  or . > let ii = var "i" (undefined::Int) > let kk = var "k" (undefined::Int) > unfoldPair $ canonicalize $ foldPair (ii,kk) (x :: Int,y :: Int)expressO(1). Unfolds an X3 representing a pair. This reverses the effect of . > value "," ((,) :: Bool->Bool->(Bool,Bool)) :$ val True :$ val False (True,False) :: (Bool,Bool) > unfoldPair $ value "," ((,) :: Bool->Bool->(Bool,Bool)) :$ val True :$ val False (True :: Bool,False :: Bool)expressO(n). Folds a list of Xs into a single X. (cf. )This always# generates an ill-typed expression. Xfold [val False, val True, val (1::Int)] [False,True,1] :: ill-typed # ExprList $ Bool #9This is useful when applying transformations on lists of X s, such as ,  or . > let ii = var "i" (undefined::Int) > let kk = var "k" (undefined::Int) > let qq = var "q" (undefined::Bool) > let notE = value "not" not > unfold . canonicalize . fold $ [ii,kk,notE :$ qq, notE :$ val False] [x :: Int,y :: Int,not p :: Bool,not False :: Bool]expressO(n). Unfolds an X$ representing a list into a list of X s. This reverses the effect of . ^> expr [1,2,3::Int] [1,2,3] :: [Int] > unfold $ expr [1,2,3::Int] [1 :: Int,2 :: Int,3 :: Int]ll (c) 2019 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela <rudy@matela.com.br>Safe5Rexpress typeclass instances provide an F function that allows values to be deeply encoded as applications of Xs. cexpr False = val False expr (Just True) = value "Just" (Just :: Bool -> Maybe Bool) :$ val True The function % can be contrasted with the function \:\! always encodes values as atomic Y Xs -- shallow encoding.. ideally encodes expressions as applications (Z ) between Y Xs -- deep encoding.>Depending on the situation, one or the other may be desirable.>Instances can be automatically derived using the TH function  .8The following example shows a datatype and its instance: (data Stack a = Stack a (Stack a) | Empty instance Express a => Express (Stack a) where expr s@(Stack x y) = value "Stack" (Stack ->>: s) :$ expr x :$ expr y expr s@Empty = value "Empty" (Empty -: s) To declare < it may be useful to use auxiliary type binding operators: , , , , , , ...+For types with atomic values, just declare  expr = val expressfType restricted version of const that forces its first argument to have the same type as the second. + value -: (undefined :: Ty) = value :: TyexpresstType restricted version of const that forces the result of its first argument to have the same type as the second. ) f ->: (undefined :: Ty) = f :: a -> TyexpressType restricted version of const that forces the result of the result of its first argument to have the same type as the second. .f ->>: (undefined :: Ty) = f :: a -> b -> TyexpressType restricted version of const that forces the result of the result of the result of its first argument to have the same type as the second.express0Forces the result type of a 4-argument function.express0Forces the result type of a 5-argument function.express0Forces the result type of a 6-argument function.express0Forces the result type of a 7-argument function.express0Forces the result type of a 8-argument function.express0Forces the result type of a 9-argument function.express1Forces the result type of a 10-argument function.express1Forces the result type of a 11-argument function.express1Forces the result type of a 12-argument function. 1111111111111 (c) 2019 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela <rudy@matela.com.br>None>Iexpress Derives an  instance for the given type  .This function needs the TemplateHaskell extension.If , , , 7, ... are not in scope, this will derive them as well.expressSame as 4 but does not warn when instance already exists ( is preferable).express Derives a  instance for a given type  3 cascading derivation of type arguments as well.(c) 2019 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela <rudy@matela.com.br>Safe@=XYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ (c) 2019 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela <rudy@matela.com.br>Safedexpress!Given two expressions, returns a n list of matches of subexpressions of the first expressions to variables in the second expression. Returns  when there is no match. > let zero = val (0::Int) > let one = val (1::Int) > let xx = var "x" (undefined :: Int) > let yy = var "y" (undefined :: Int) > let e1 -+- e2 = value "+" ((+)::Int->Int->Int) :$ e1 :$ e2 S> (zero -+- one) `match` (xx -+- yy) Just [(y :: Int,1 :: Int),(x :: Int,0 :: Int)] a> (zero -+- (one -+- two)) `match` (xx -+- yy) Just [(y :: Int,1 + 2 :: Int),(x :: Int,0 :: Int)] ?> (zero -+- (one -+- two)) `match` (xx -+- (yy -+- yy)) Nothing In short:  (zero -+- one) `match` (xx -+- yy) = Just [(xx,zero), (yy,one)] (zero -+- (one -+- two)) `match` (xx -+- yy) = Just [(xx,zero), (yy,one-+-two)] (zero -+- (one -+- two)) `match` (xx -+- (yy -+- yy)) = NothingexpressLike " but allowing predefined bindings. matchWith [(xx,zero)] (zero -+- one) (xx -+- yy) = Just [(xx,zero), (yy,one)] matchWith [(xx,one)] (zero -+- one) (xx -+- yy) = Nothingexpress Given two X_s, checks if the first expression is an instance of the second in terms of variables. (cf. ) > let zero = val (0::Int) > let one = val (1::Int) > let xx = var "x" (undefined :: Int) > let yy = var "y" (undefined :: Int) > let e1 -+- e2 = value "+" ((+)::Int->Int->Int) :$ e1 :$ e2  one `isInstanceOf` one = True xx `isInstanceOf` xx = True yy `isInstanceOf` xx = True zero `isInstanceOf` xx = True xx `isInstanceOf` zero = False one `isInstanceOf` zero = False (xx -+- (yy -+- xx)) `isInstanceOf` (xx -+- yy) = True (yy -+- (yy -+- xx)) `isInstanceOf` (xx -+- yy) = True (zero -+- (yy -+- xx)) `isInstanceOf` (zero -+- yy) = True (one -+- (yy -+- xx)) `isInstanceOf` (zero -+- yy) = Falseexpress:Checks if any of the subexpressions of the first argument X( is an instance of the second argument X.expressO(n^2). Checks if an X is a subexpression of another. 5> (xx -+- yy) `isSubexprOf` (zz -+- (xx -+- yy)) True 2> (xx -+- yy) `isSubexprOf` abs' (yy -+- xx) False > xx `isSubexprOf` yy False(c) 2019 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela <rudy@matela.com.br>SafeexpressO(1). Reifies an  instance into a list of Xs. The list will contain  and  for the given type. (cf. , ) X> reifyEq (undefined :: Int) [ (==) :: Int -> Int -> Bool , (/=) :: Int -> Int -> Bool ] ]> reifyEq (undefined :: Bool) [ (==) :: Bool -> Bool -> Bool , (/=) :: Bool -> Bool -> Bool ] g> reifyEq (undefined :: String) [ (==) :: [Char] -> [Char] -> Bool , (/=) :: [Char] -> [Char] -> Bool ]expressO(1). Reifies an  instance into a list of Xs. The list will contain ,  and  for the given type. (cf. , , , ) X> reifyOrd (undefined :: Int) [ (<=) :: Int -> Int -> Bool , (<) :: Int -> Int -> Bool ] ]> reifyOrd (undefined :: Bool) [ (<=) :: Bool -> Bool -> Bool , (<) :: Bool -> Bool -> Bool ] g> reifyOrd (undefined :: [Bool]) [ (<=) :: [Bool] -> [Bool] -> Bool , (<) :: [Bool] -> [Bool] -> Bool ]expressO(1). Reifies  and  instances into a list of X.expressO(1). Reifies a  instance into a list of Xs. The list will contain  for the given type. (cf. , , ) 6> reifyName (undefined :: Int) [name :: Int -> [Char]] 8> reifyName (undefined :: Bool) [name :: Bool -> [Char]]expressO(1). Builds a reified  instance from the given  function. (cf. ) _> mkEq ((==) :: Int -> Int -> Bool) [ (==) :: Int -> Int -> Bool , (/=) :: Int -> Int -> Bool ]expressO(1). Builds a reified  instance from the given  function. (cf. , )expressO(1). Builds a reified  instance from the given  function. (cf. , )expressO(1). Builds a reified  instance from the given  function. (cf. , )expressO(1). Builds a reified  instance from the given  and type. (cf. , )expressO(n). Returns whether an < instance exists in the given instances list for the given . H> isEqT (reifyEqOrd (undefined :: Int)) (typeOf (undefined :: Int)) True O> isEqT (reifyEqOrd (undefined :: Int)) (typeOf (undefined :: [[[Int]]])) False)Given that the instances list has length n, this function is O(n).expressO(n). Returns whether an < instance exists in the given instances list for the given . I> isOrdT (reifyEqOrd (undefined :: Int)) (typeOf (undefined :: Int)) True P> isOrdT (reifyEqOrd (undefined :: Int)) (typeOf (undefined :: [[[Int]]])) False)Given that the instances list has length n, this function is O(n).expressO(n). Returns whether both  and 1 instance exist in the given list for the given .)Given that the instances list has length n, this function is O(n).expressO(n+m). Returns whether an < instance exists in the given instances list for the given X. :> isEq (reifyEqOrd (undefined :: Int)) (val (0::Int)) True A> isEq (reifyEqOrd (undefined :: Int)) (val ([[[0::Int]]])) False)Given that the instances list has length m and that the given X has size n, this function is O(n+m).expressO(n+m). Returns whether an < instance exists in the given instances list for the given X. ;> isOrd (reifyEqOrd (undefined :: Int)) (val (0::Int)) True B> isOrd (reifyEqOrd (undefined :: Int)) (val ([[[0::Int]]])) False)Given that the instances list has length m and that the given X has size n, this function is O(n+m).expressO(n+m). Returns whether both  and 1 instance exist in the given list for the given X.)Given that the instances list has length m and that the given X has size n, this function is O(n+m).1(c) 2019 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela <rudy@matela.com.br>Safe expressLike @ but allows customization of the list of variable names. (cf. , ) I> canonicalizeWith (const ["i","j","k","l",...]) (xx -+- yy) i + j :: Int The argument X[ of the argument function allows to provide a different list of names for different types: > let namesFor e > | typ e == typeOf (undefined::Char) = variableNamesFromTemplate "c1" > | typ e == typeOf (undefined::Int) = variableNamesFromTemplate "i" > | otherwise = variableNamesFromTemplate "x" f> canonicalizeWith namesFor ((xx -+- ord' dd) -+- (ord' cc -+- yy)) (i + ord c1) + (ord c2 + j) :: IntexpressLike @ but allows customization of the list of variable names. (cf. , )expressLike 3 but allows specifying the list of variable names.expressCanonicalizes an XL so that variable names appear in order. Variable names are taken from the . '> canonicalize (xx -+- yy) x + y :: Int '> canonicalize (yy -+- xx) x + y :: Int '> canonicalize (xx -+- xx) x + x :: Int '> canonicalize (yy -+- yy) x + x :: IntConstants are untouched: A> canonicalize (jj -+- (zero -+- abs' ii)) x + (y + abs y) :: Int'This also works for variable functions: C> canonicalize (gg yy -+- ff xx -+- gg xx) (f x + g y) + f y :: Intexpress Return a canonicalization of an X3 that makes variable names appear in order using  as provided by  . By using  it can  Xs. > canonicalization (gg yy -+- ff xx -+- gg xx) [ (x :: Int, y :: Int) , (f :: Int -> Int, g :: Int -> Int) , (y :: Int, x :: Int) , (g :: Int -> Int, f :: Int -> Int) ] U> canonicalization (yy -+- xx -+- yy) [ (x :: Int, y :: Int) , (y :: Int, x :: Int) ]expressReturns whether an X is canonical: if applying  is an identity using  as provided by .express'Returns all canonical variations of an Xn by filling holes with variables. Where possible, variations are listed from most general to least general. %> canonicalVariations $ i_ [x :: Int] A> canonicalVariations $ i_ -+- i_ [ x + y :: Int , x + x :: Int ] > canonicalVariations $ i_ -+- i_ -+- i_ [ (x + y) + z :: Int , (x + y) + x :: Int , (x + y) + y :: Int , (x + x) + y :: Int , (x + x) + x :: Int ] 9> canonicalVariations $ i_ -+- ord' c_ [x + ord c :: Int] a> canonicalVariations $ i_ -+- i_ -+- ord' c_ [ (x + y) + ord c :: Int , (x + x) + ord c :: Int ] > canonicalVariations $ i_ -+- i_ -+- length' (c_ -:- unit c_) [ (x + y) + length (c:d:"") :: Int , (x + y) + length (c:c:"") :: Int , (x + x) + length (c:d:"") :: Int , (x + x) + length (c:c:"") :: Int ]hIn an expression without holes this functions just returns a singleton list with the expression itself: 1> canonicalVariations $ val (0 :: Int) [0 :: Int] 1> canonicalVariations $ ord' bee [ord 'b' :: Int] 0> canonicalVariations $ ii -+- jj [i + j :: Int]`Behaviour is undefined when applying this function to expressions already containing variables.expressA faster version of  that disregards name clashes across different types. Results are confusing to the user but fine for Express which differentiates between variables with the same name but different types.Without applying , the following X% may seem to have only one variable: => fastCanonicalVariations $ i_ -+- ord' c_ [x + ord x :: Int](Where in fact it has two, as the second  x ! has a different type. Applying  disambiguates: P> map canonicalize . fastCanonicalVariations $ i_ -+- ord' c_ [x + ord c :: Int]'This function is useful when resulting Xs are not intended to be presented to the user but instead to be used by another function. It is simply faster to skip the step where clashes are resolved.expressFill holes in an expression. Silently skips holes that are not of the right type. Silently discard remaining expressions.(c) 2019 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela <rudy@matela.com.br>NoneٽpDEFXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~pXYZ[\]^def_`agqrpobcmnk{|}~jihsuywtvzxlDFE(c) 2019 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela <rudy@matela.com.br>NoneICexpressX representing a hole of  type. > b_ _ :: BoolexpressX representing a variable p :: . > pp p :: BoolexpressX representing a variable q :: . > qq q :: BoolexpressX representing a variable r :: . > rr r :: BoolexpressX representing a variable p' :: . > pp' p' :: Boolexpress encoded as an X. > false False :: Boolexpress encoded as an X. > true True :: Boolexpress The function  encoded as an X. > notE not :: Bool -> Boolexpress The function k encoded as an X. #> andE (&&) :: Bool -> Bool -> Boolexpress The function j encoded as an X. "> orE (||) :: Bool -> Bool -> Boolexpress The function  lifted over the X type. > not' false not False :: Bool > evalBool $ not' false True > not' pp not p :: Boolexpress The function  lifted over the X type. > pp -&&- qq p && q :: Bool '> false -&&- true False && True :: Bool "> evalBool $ false -&&- true Falseexpress The function  lifted over the X type. > pp -||- qq p || q :: Bool '> false -||- true False || True :: Bool !> evalBool $ false -||- true TrueexpressA typed hole of  type.  > i_ _ :: Intexpress A variable x of  type.  > xx x :: Intexpress A variable y of  type.  > yy y :: Intexpress A variable z of  type.  > zz z :: Intexpress A variable x' of  type. > xx' x' :: Intexpress The value 0 bound to the  type encoded as an X. > zero 0 :: Intexpress The value 1 bound to the  type encoded as an X. > one 1 :: Intexpress The value 2 bound to the  type encoded as an X. > two 2 :: Intexpress The value 3 bound to the  type encoded as an X. > three 3 :: Intexpress The value -1 bound to the  type encoded as an X. > minusOne -1 :: Intexpress The value -2 bound to the  type encoded as an X. > minusOne -2 :: IntexpressA variable function f& of 'Int -> Int' type lifted over the X type. > ff xx f x :: Int > ff one f 1 :: Intexpress A variable f$ of 'Int -> Int' type encoded as an X. > ffE f :: Int -> IntexpressA variable function g& of 'Int -> Int' type lifted over the X type. > gg yy g y :: Int > gg minusTwo gg (-2) :: IntexpressA variable binary operator ? lifted over the X type. Works for , , , [Int] and . > xx -?- yy x ? y :: Int > pp -?- qq p ? q :: Bool t> xx -?- qq *** Exception: (-?-): cannot apply `(?) :: * -> * -> *` to `x :: Int' and `q :: Bool'. Unhandled types?express A variable g$ of 'Int -> Int' type encoded as an X. > ggE g :: Int -> Int express The operator  for the  type for use on Xs. (See also  .) > two -+- three 2 + 3 :: Int 9> minusOne -+- minusTwo -+- zero ((-1) + (-2)) + 0 :: Int '> xx -+- (yy -+- zz) x + (y + z) :: Int express The operator  for the  type. (See also  .) > plus (+) :: Int -> Int -> Int !> plus :$ one (1 +) :: Int -> Int > plus :$ xx :$ yy x + y :: Int express The operator  for the  type lifted over the X type. (See also  .) > three -*- three 9 :: Int *> one -*- two -*- three (1 * 2) * 3 :: Int > two -*- xx 2 * x :: Int express The operator  for the  type. (See also  .)  > times (*) :: Int -> Int -> Int "> times :$ two (2 *) :: Int -> Int  > times :$ xx :$ yy x * y :: Int expressConstructs an application of  as an X. Only works for , , , , [Int], [Bool]. > id' yy id yy :: Int > id' one id 1 :: Int > evl (id' one) :: Int 1 > id' pp id p :: Bool > id' false id' False :: Bool %> evl (id' true) :: Bool True :: Boolexpress The function  for the  type encoded as an X . (See also  .) > idE :$ xx id x :: Int > idE :$ zero id 0 :: Int ,> evaluate $ idE :$ zero :: Maybe Int Just 0express The function  encoded as an X. (cf.  )express The function  encoded as an X. (cf.  )express The function  encoded as an X. (cf.  )express The function  encoded as an X. (cf.  )express The function  encoded as an X. (cf.  )express The function  encoded as an X. (cf.  )express over the  type lifted over the X type. > negate' xx negate x :: Int > evl (negate' one) :: Int -1express over the  type encoded as an X > negateE negate :: Int -> Intexpress over the  type lifted over the X type. > abs' xx' abs x' :: Int > evl (abs' minusTwo) :: Int 2express over the  type encoded as an X. > absE abs :: Int -> Intexpress A hole of  type encoded as an X. > c_ _ :: Char!expressThe character 'b' encoded as an X > bee 'b' :: Char > evl bee :: Char 'b'"expressThe character 'c' encoded as an X > cee 'c' :: Char > evl cee :: Char 'c'#expressThe character 'd' encoded as an X > dee 'd' :: Char > evl dee :: Char 'd'(expressA typed hole of [Int] type encoded as an X. > is_ _ :: [Int])expressA variable named xs of type [Int] encoded as an X. > xxs xs :: [Int]*expressA variable named ys of type [Int] encoded as an X. > yys ys :: [Int]+expressAn empty list of type [Int] encoded as an X. > nil [] :: [Int],express An empty  encoded as an X. > emptyString "" :: String-express"The empty list '[]' encoded as an X..express"The empty list '[]' encoded as an X./express"The empty list '[]' encoded as an X.0expressThe list constructor with  as element type encoded as an X. #> cons (:) :: Int -> [Int] -> [Int] !> cons :$ one :$ nil [1] :: [Int]Consider using 5 and 4 when building lists of X.1expressThe list constructor  :  encoded as an X.2expressThe list constructor  :  encoded as an X.3expressThe list constructor  :  encoded as an X.4express4M constructs a list with a single element. This works for elements of type ,  and . > unit one [1] > unit false [False]5express%The list constructor lifted over the X& type. Works for the element types ,  and . ,> zero -:- one -:- unit two [0,1,2] :: [Int] /> zero -:- one -:- two -:- nil [0,1,2] :: [Int] !> bee -:- unit cee "bc" :: [Char]6express#List concatenation lifted over the X& type. Works for the element types ,  and . N> (zero -:- one -:- nil) -:- (two -:- three -:- nil) [0,1] -++- [2,3] :: [Int] 9> (bee -:- unit cee) -:- unit dee "bc" -++- "c" :: [Char]7expressList  lifted over the X& type. Works for the element types ,  and . "> head' $ unit one head [1] :: Int #> head' $ unit bee head "b" :: Char -> head' $ zero -:- unit two head [0,2] :: Int !> evl $ head' $ unit one :: Int 18expressList  lifted over the X& type. Works for the element types ,  and . $> tail' $ unit one tail [1] :: [Int] %> tail' $ unit bee tail "b" :: [Char] /> tail' $ zero -:- unit two tail [0,2] :: [Int] .> evl $ tail' $ zero -:- unit two :: [Int] [2]9expressList X lifted over the X& type. Works for the element types ,  and . &> length' $ unit one length [1] :: Int &> length' $ unit bee length "b" :: Int 1> length' $ zero -:- unit two length [0,2] :: Int #> evl $ length' $ unit one :: Int 1DEFXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOj>?@AB     = !"#$%&'()*+,-./0123546789<:;CDEHFGKJILMNO 65565=6>4?4@4A4 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~   N       !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdbefbcgbchbeibjkbjlbjmbjnbjobjpbjqbjrbjsbjtbjubjvbwxbyzby{bj|bj}bj~bjbjbjbjbjbjbjbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb b b b b bbbbbbbbbbbbbbbbbbb b!"b#$b#%be&be'()*()(+,(+-(+.(+/(+0(+1(+2(+3(+4(+5(+6(+7(+8(+9(+:(+;(+<(+=(+>(+?(+@(+A(+B(+C(+D(+E(+(+F(+G(+H(+I(+J(+K(+L(+M(+N(+O(+P(+Q(+R(+S(+T(+U(+V(+W(+X(+Y(+Z(+[(+\(+](+^(+_(+`(+a(+b(+c(+d(+e(+f(+g(+h(+i(+j(+k(+l(+m(+n(+o(+p(+q(+r(+s(+t(+u(+v(+w(+x(+y(+z(+{(+|(+}(+~(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()(+(+()()()()()()()()()()()()()()()()()()(+(+(+(+(+()()()()()()()()()()()()()()() () () () () ()()()()()()()()()()()()()()()()()()() ()!()"()#()$()%()&()'()((+)(+*()+(),())(+-(+.(+/()0()0()1(+2(+3(+4(+5(+6()7()8()9()9(+:();()<()=()>()?(+@(+A(+B(+C(+D(+EFGHFGIFGJFGKFGLFGMFGNFGOFGPFGQFGRFGSFGTFGUFGVFGWFGXFGYFGZFG[FG\FG]FG^FG_FG`FGaFGbFGcFGdFGeFGfFGgFGhFGiFGjFGkFGlFGmFGnFGoFGpFGqFGrFGsFGtFGuFGvFGwFGxFGyFGzFG{FG|FG}FG~FGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFGFG((((((((((((((((((((((+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+(+((((((((()()() () () () () ()()()()()()()()()()()()()()()()()()() ()!()"()#()$()%()&()'()'()(())()*()+(),()-().()/()0()1()2()3()4()5()6()7()7()8()9():();()<()=()>()>()?()@()A()B()C()D()E()F()G()H()I()J()K()L()M()N()O()P()Q()R()S()T()U()V()W()X()Y()Z()[()\()]()^()^()_()`()a()b()c()d()e()e()f()f()g()h()i()j()k()l()m()n()o()p()q()r()s()t()u()v()w()x()y()z(){()|()}()|()~()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb#bbbbb#bbbebb$express-0.1.2-IuNtDShv85NGqUxc6jXvqsData.Express.Utils.ListData.Express.Utils.StringData.Express.NameData.Express.Utils.THData.Express.Name.DeriveData.Express.Utils.TypeableData.Express.CoreData.Express.MapData.Express.HoleData.Express.FoldData.Express.ExpressData.Express.Express.DeriveData.Express.MatchData.Express.InstancesData.Express.CanonData.Express.Fixtures canonicalize mapValuescanonicalVariations deriveExpressData.Express.Basic Data.ExpressnubSort nubSortBy isSubsetOfisPermutationOfisNublookupId+++unquoteatomicouternmostPrecisNegativeLiteralisInfixprecisPrefixisInfixedPrefixtoPrefix primeCyclevariableNamesFromTemplateNamenamenames$fName(,,,,,,,,,,,)$fName(,,,,,,,,,,)$fName(,,,,,,,,,)$fName(,,,,,,,,)$fName(,,,,,,,)$fName(,,,,,,) $fName(,,,,,) $fName(,,,,) $fNameWord$fName[] $fName(,,,) $fName(,,) $fName(,) $fNameEither $fNameMaybe$fName-> $fNameDouble $fNameFloat $fNameRatio$fNameOrdering $fNameChar $fNameInteger $fNameInt $fNameBool$fName()deriveWhenNeededderiveWhenNeededOrWarn showJustNamereallyDeriveCascading typeConArgstypeConArgsThattypeConCascadingArgsThat normalizeTypenormalizeTypeUnits isInstanceOfisntInstanceOf typeAritytypeConstructors isTypeSynonymtypeSynonymType|=>||++| mergeIFnsmergeIwhereItypeConstructorsArgNames lookupValN deriveNamederiveNameIfNeededderiveNameCascading compareTytyArity finalResultTyunFunTy argumentTyresultTy elementTyboolTyintTy orderingTyfunTyConisFunTymkComparisonTy mkCompareTytypesIn typesInList->::ExprValue:$valueval$$vartypetypmtyp isIllTyped isWellTypedevaluateevalevl toDynamic showOpExpr showPrecExprshowExprcompareComplexity unfoldApphasVarisGroundisConstisVarisValueisAppsubexprs nubSubexprsvalues nubValuesconsts nubConstsvarsnubVarsaritysizedepthheight $fOrdExpr$fEqExpr $fShowExprmapVars mapConsts mapSubexprs//-// renameVarsBy varAsTypeOf holeAsTypeOfholeisHoleholesnubHoleslistVarslistVarsAsTypeOffoldAppfoldPair unfoldPairfoldTrio unfoldTriofoldunfoldExpressexpr-:->:->>:->>>:->>>>:->>>>>:->>>>>>: ->>>>>>>: ->>>>>>>>: ->>>>>>>>>: ->>>>>>>>>>: ->>>>>>>>>>>:->>>>>>>>>>>>:$fExpress(,,,,,,,,,,,)$fExpress(,,,,,,,,,,)$fExpress(,,,,,,,,,)$fExpress(,,,,,,,,)$fExpress(,,,,,,,)$fExpress(,,,,,,)$fExpress(,,,,,)$fExpress(,,,,)$fExpressRatio $fExpress[]$fExpress(,,,) $fExpress(,,) $fExpress(,)$fExpressEither$fExpressMaybe$fExpressOrdering $fExpressChar$fExpressInteger $fExpressInt $fExpressBool $fExpress()deriveExpressIfNeededderiveExpressCascadingmatch matchWith hasInstanceOf isSubexprOfreifyEqreifyOrd reifyEqOrd reifyNamemkEqmkOrdmkOrdLessEqualmkName mkNameWithlookupComparisonisEqTisOrdTisEqOrdTisEqisOrdisEqOrd mkComparison mkEquationmkComparisonLTmkComparisonLE lookupName lookupNames listVarsWith validApps findValidApppreludeNameInstancescanonicalizeWithcanonicalizationWithisCanonicalWithcanonicalization isCanonicalfastCanonicalVariationsb_ppqqrrpp'falsetruenotEandEorE-==>-impliesnot'-&&--||-i_xxyyzzxx'iijjkkii'zeroonetwothreeminusOneminusTwoffffEgg-?-ggE-+-plus-*-timesid'idEidIntidBoolidCharidIntsidBoolsidStringconst'negate'negateEabs'absEodd'even'c_ccddccsaebeeceedeespace lineBreakord'ordEis_xxsyysnil emptyStringnilIntnilBoolnilCharconsconsIntconsBoolconsCharunit-:--++-head'tail'length'sort'insert'elem'-$--==--/=--<=--<-compare'nothing nothingInt nothingBooljustIntjustBooljust-|-paircommatriple quadruple quintuplesixtuplebaseGHC.ListlookupGHC.Base++filterzipmap Data.Foldablefoldlfoldrnulllengthfoldl'foldl1sumproductfoldr1maximumminimumelem Data.ListisSubsequenceOfData.Traversable mapAccumR mapAccumLfindnotElem minimumBy maximumByallanyorand concatMapconcat Data.OldListunwordswordsunlineslinesunfoldrsortOnsortBysort permutations subsequencestailsinitsgroupBygroupdeleteFirstsByunzip7unzip6unzip5unzip4zipWith7zipWith6zipWith5zipWith4zip7zip6zip5zip4genericReplicate genericIndexgenericSplitAt genericDrop genericTake genericLengthinsertByinsert partition transpose intercalate intersperse intersectBy intersectunionByunion\\deleteBydeletenubBynub isInfixOf isSuffixOf isPrefixOf findIndices findIndex elemIndices elemIndex stripPrefix dropWhileEndunzip3unzipzipWith3zipWithzip3!!reversebreakspansplitAtdroptake dropWhile takeWhilecycle replicaterepeatiterate'iteratescanr1scanrscanl'scanl1scanlfoldl1'initlasttailunconshead Data.StringIsString fromStringghc-prim GHC.TypesChar Data.Char isSeparatorisNumberisMarkisLetter digitToIntGHC.Read readLitChar lexLitChar GHC.UnicodetoTitletoUppertoLowerisLowerisUpperisPrint isControl isAlphaNumisAlphaisSymbol isPunctuation isHexDigit isOctDigitisDigitisSpace isAsciiUpper isAsciiLowerisLatin1isAsciigeneralCategoryGeneralCategoryFormatControlUppercaseLetterLowercaseLetterTitlecaseLetterModifierLetter OtherLetterNonSpacingMarkSpacingCombiningMark EnclosingMark DecimalNumber LetterNumber OtherNumberConnectorPunctuationDashPunctuationOpenPunctuationClosePunctuation InitialQuote FinalQuoteOtherPunctuation MathSymbolCurrencySymbolModifierSymbol OtherSymbolSpace LineSeparatorParagraphSeparator Surrogate PrivateUse NotAssignedGHC.CharchrGHC.Show intToDigit showLitCharordStringtemplate-haskellLanguage.Haskell.TH.SyntaxnewName Language.Haskell.TH.Lib.InternalcharLstringLintegerLintPrimL wordPrimL floatPrimL doublePrimL rationalL stringPrimL charPrimLlitPvarPtupP unboxedTupP unboxedSumPconPinfixPtildePbangPasPwildPrecPlistPsigPviewPfieldPatclausevarEconElitEappEappTypeEinfixEinfixAppsectionLsectionRlamElamCaseEtupE unboxedTupE unboxedSumEcondEmultiIfEletEcaseEdoEcompEfromE fromThenEfromToE fromThenToElistEsigErecConErecUpdEstaticE unboundVarElabelEfieldExpguardedBnormalBnormalGEpatGEbindSletSnoBindSparSfunDvalDinstanceWithOverlapDsigDforImpDpragInlD pragSpecD pragSpecInlD pragSpecInstD pragRuleDpragAnnD tySynInstDinfixLDinfixRDinfixND roleAnnotD defaultSigDpatSynD patSynSigD pragCompleteDcxtnoSourceUnpackednesssourceNoUnpack sourceUnpacknoSourceStrictness sourceLazy sourceStrictnormalCrecCinfixCgadtCrecGadtCbangbangType varBangTypeunidir implBidir explBidir prefixPatSyn infixPatSyn recordPatSynvarTconTtupleT unboxedTupleT unboxedSumTarrowTlistTappT equalityTlitT promotedTpromotedTupleT promotedNilT promotedConsT wildCardTnumTyLitstrTyLitnominalRrepresentationalRphantomRinferRvarKconKtupleKarrowKlistKappKinjectivityAnncCallstdCallcApiprim javaScriptunsafesafe interruptiblefunDeptySynEqnruleVar typedRuleVarvalueAnnotationtypeAnnotationmoduleAnnotationExpVarEConELitEAppEAppTypeEInfixEUInfixEParensELamELamCaseETupE UnboxedTupE UnboxedSumECondEMultiIfELetECaseEDoECompE ArithSeqEListESigERecConERecUpdEStaticE UnboundVarELabelEMatchClauseQExpQDecQPatLitPVarPTupP UnboxedTupP UnboxedSumPConPInfixPUInfixPParensPTildePBangPAsPWildPRecPListPSigPViewPMatchQClauseQStmtQConQTypeQTypeListTForallTAppTSigTVarTConT PromotedTInfixTUInfixTParensTTupleT UnboxedTupleT UnboxedSumTArrowT EqualityTPromotedTupleT PromotedNilT PromotedConsTStarT ConstraintTLitT WildCardTDecFunDValDDataDNewtypeDTySynDClassD InstanceDSigDForeignDInfixDPragmaD DataFamilyD DataInstD NewtypeInstD TySynInstDOpenTypeFamilyDClosedTypeFamilyD RoleAnnotDStandaloneDerivD DefaultSigDPatSynD PatSynSigD BangTypeQ VarBangTypeQFieldExpFieldPatPatQ FieldPatQ FieldExpQFunDepPredPredQ TyVarBndrQDecsQ RuleBndrQ TySynEqnQTExpunTypeInjectivityAnnKindQOverlap Overlappable OverlappingOverlaps Incoherent DerivClauseQDerivStrategyQ stockStrategyanyclassStrategynewtypeStrategy viaStrategyghc-boot-th-8.6.5GHC.LanguageExtensions.Type ExtensionCppOverlappingInstancesUndecidableInstancesIncoherentInstancesUndecidableSuperClassesMonomorphismRestriction MonoPatBindsMonoLocalBindsRelaxedPolyRecExtendedDefaultRulesForeignFunctionInterfaceUnliftedFFITypesInterruptibleFFICApiFFIGHCForeignImportPrim JavaScriptFFIParallelArraysArrowsTemplateHaskellTemplateHaskellQuotes QuasiQuotesImplicitParamsImplicitPreludeScopedTypeVariablesAllowAmbiguousTypes UnboxedTuples UnboxedSums BangPatterns TypeFamiliesTypeFamilyDependencies TypeInTypeOverloadedStringsOverloadedLists NumDecimalsDisambiguateRecordFieldsRecordWildCards RecordPuns ViewPatternsGADTs GADTSyntaxNPlusKPatternsDoAndIfThenElseBlockArgumentsRebindableSyntaxConstraintKinds PolyKinds DataKinds InstanceSigs ApplicativeDoStandaloneDerivingDeriveDataTypeableAutoDeriveTypeable DeriveFunctorDeriveTraversableDeriveFoldable DeriveGenericDefaultSignaturesDeriveAnyClass DeriveLiftDerivingStrategies DerivingViaTypeSynonymInstancesFlexibleContextsFlexibleInstancesConstrainedClassMethodsMultiParamTypeClassesNullaryTypeClassesFunctionalDependencies UnicodeSyntaxExistentialQuantification MagicHashEmptyDataDeclsKindSignaturesRoleAnnotationsParallelListCompTransformListCompMonadComprehensionsGeneralizedNewtypeDeriving RecursiveDoPostfixOperators TupleSections PatternGuardsLiberalTypeSynonyms RankNTypesImpredicativeTypes TypeOperatorsExplicitNamespacesPackageImportsExplicitForAllAlternativeLayoutRule!AlternativeLayoutRuleTransitionalDatatypeContextsNondecreasingIndentation RelaxedLayoutTraditionalRecordSyntax LambdaCase MultiWayIfBinaryLiteralsNegativeLiteralsHexFloatLiteralsDuplicateRecordFieldsOverloadedLabels EmptyCasePatternSynonymsPartialTypeSignaturesNamedWildCardsStaticPointersTypeApplicationsStrict StrictDataMonadFailDesugaringEmptyDataDerivingNumericUnderscoresQuantifiedConstraints StarIsTypeLanguage.Haskell.TH.LibstandaloneDerivWithStrategyD derivClausetyVarSigkindSignoSig constraintKstarKkindedTVplainTVsigTforallTforallCclosedTypeFamilyDopenTypeFamilyD dataFamilyD newtypeInstD dataInstDclassDnewtypeDdataDtySynD thisModuleappsE varStrictType strictTypeunpacked notStrictisStrictequalPclassPparensTuInfixTinfixTstandaloneDerivD pragLineD instanceDstringE arithSeqElam1EuInfixEparensEdynpatGnormalG fromThenToRfromToR fromThenRfromRparensPuInfixPInfoQTExpQTyLitQCxtQBodyQGuardQRangeQSourceStrictnessQSourceUnpackednessQBangQ StrictTypeQVarStrictTypeQ PatSynDirQ PatSynArgsQFamilyResultSigQLanguage.Haskell.TH.Ppr pprParendTypepprPatpprLitpprExppprintPprpprppr_list defaultFixity maxPrecedenceunboxedSumTypeNameunboxedSumDataNameunboxedTupleTypeNameunboxedTupleDataName tupleTypeName tupleDataName nameSpace namePackage nameModulenameBase extsEnabled isExtEnabledrunIOlocation isInstancereifyConStrictness reifyModulereifyAnnotations reifyRolesreifyInstances reifyFixityreifylookupValueNamelookupTypeNamerecover reportWarning reportErrorreportrunQ NameSpaceLoc loc_filename loc_package loc_module loc_startloc_endInfoClassIClassOpITyConIFamilyI PrimTyConIDataConIPatSynIVarITyVarI ModuleInfo ParentNameSumAltSumArityArityUnlifted InstanceDecFixityFixityDirectionInfixLInfixRInfixNLitCharLStringLIntegerL RationalLIntPrimL WordPrimL FloatPrimL DoublePrimL StringPrimL CharPrimLBodyGuardedBNormalBGuardNormalGPatGStmtBindSLetSNoBindSParSRangeFromR FromThenRFromToR FromThenToR DerivClause DerivStrategy StockStrategyAnyclassStrategyNewtypeStrategy ViaStrategy PatSynTypeTypeFamilyHeadTySynEqnForeignImportFExportFCallconvCCallStdCallCApiPrim JavaScriptSafetySafeUnsafe InterruptiblePragmaInlineP SpecialisePSpecialiseInstPRulePAnnPLineP CompletePInlineNoInline Inlinable RuleMatchConLikeFunLikePhases AllPhases FromPhase BeforePhaseRuleBndrRuleVar TypedRuleVar AnnTargetModuleAnnotationTypeAnnotationValueAnnotationCxtSourceUnpackedness SourceUnpackSourceNoUnpackNoSourceUnpackednessSourceStrictness SourceLazy SourceStrictNoSourceStrictnessDecidedStrictness DecidedLazy DecidedStrict DecidedUnpackConNormalCRecCInfixCForallCGadtCRecGadtCBang PatSynDirUnidir ImplBidir ExplBidir PatSynArgs PrefixPatSyn InfixPatSyn RecordPatSyn TyVarBndrPlainTVKindedTVFamilyResultSigNoSigKindSigTyVarSigTyLitNumTyLitStrTyLitRoleNominalRRepresentationalRPhantomRInferR AnnLookupAnnLookupModule AnnLookupNameKind Data.TypeablemkFunTyData.Typeable.InternalTypeableTyContypeOf7typeOf6typeOf5typeOf4typeOf3typeOf2typeOf1 rnfTypeReptypeRepFingerprint typeRepTyCon typeRepArgs splitTyConApp funResultTygcast2gcast1gcasteqTcast showsTypeReptypeReptypeOfTypeReprnfTyContyConFingerprint tyConName tyConModule tyConPackage Data.ProxyProxyData.Type.Equality:~:Refl:~~:HReflShow Data.DynamicDynamic GHC.MaybeJustNothingGHC.Err undefinedshow unfoldTuple GHC.ClassesEq==/=Ordcompare<=<-:>fillBoolFalseTruenot&&||IntGHC.Num+*idnegateabs