h$m      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                                                       (c) 2019-2021 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-Inferred express O(n log n)0. Sorts and remove repetitions. Equivalent to  nub . sort. > 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]expressLike $ but allows providing a function to  values.express O(n log n). Checks that all elements of the first list are elements of the second.express O(n log n). 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: isNub [] = True isNub [1,2,3] = True isNub [2,1,2] = FalseexpressO(n). Like 0 but returns the key itself if nothing is found. > lookupId 5 [(1,2),(3,4)] 5 "> lookupId 5 [(1,2),(3,4),(5,6)] 6express.Merges two lists discarding repeated elements.'The argument lists need to be in order. *> [1,10,100] +++ [9,10,11] [1,9,10,11,100]5(c) 2016-2021 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-Inferred expressUnquotes a string if possible, otherwise, this is just an identity. > unquote "\"string\"" "string" +> unquote "something else" "something else"express8Checks if a string-encoded Haskell expression is atomic. > 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: > 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. express3Returns the operator precedence of an infix string. > outernmostPrec "1 + 2" Just 6 expressReturns whether the given  represents a negative literal. > isNegativeLiteral "1" False > isNegativeLiteral "-1" True > isNegativeLiteral "-x" False > isNegativeLiteral "1 - 3" False express'Check if a function / operator is infix isInfix "foo" == False isInfix "(+)" == False isInfix "`foo`" == True isInfix "+" == True express3Returns the precedence of default Haskell operators express&Is the given string a prefix function? > isPrefix "abs" True > isPrefix "+" FalseexpressIs the string of the form `string`express3Transform an infix operator into an infix function: 3toPrefix "`foo`" == "foo" toPrefix "+" == "(+)"expressCycles through a list of variable names priming them at each iteration. primeCycle ["x","y","z"] 7"x","y","z","x'","y'","z'","x''","y''","z''","x'''",...expressReturns 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'", ...] > variableNamesFromTemplate "xy" ["xy", "zw", "xy'", "zw'", "xy''", ...]    (c) 2019-2021 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-Inferred (c) 2019-2021 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-Inferred&`expressIf 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 : > names (undefined :: Int) ["x", "y", "z", "x'", "y'", "z'", "x''", "y''", "z''", ...] > names (undefined :: Bool) ["p", "q", "r", "p'", "q'", "r'", "p''", "q''", "r''", ...] > 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"expressReturns na infinite list of variable names from the given type: the result of  after . > names (undefined :: Int) ["x", "y", "z", "x'", "y'", "z'", "x''", "y''", "z''", ...] > names (undefined :: Bool) ["p", "q", "r", "p'", "q'", "r'", "p''", "q''", "r''", ...] > names (undefined :: [Int]) ["xs", "ys", "zs", "xs'", "ys'", "zs'", "xs''", "ys''", ...]'express names (undefined :: [Int]) = ["xs", "ys", "zs", "xs'", ...] names (undefined :: [Bool]) = ["ps", "qs", "rs", "ps'", ...](express names (undefined :: ((),(),(),())) = ["uuuu", "uuuu1", ...] names (undefined :: (Int,Int,Int,Int)) = ["xxxx", ...])express names (undefined :: (Int,Int,Int)) = ["xyz","uvw", ...] names (undefined :: (Int,Bool,Char)) = ["xpc", "xpc1", ...]*express names (undefined :: (Int,Int)) = ["xy", "zw", "xy'", ...] names (undefined :: (Bool,Bool)) = ["pq", "rs", "pq'", ...]+express names (undefined :: Either Int Int) = ["exy", "exy1", ...] names (undefined :: Either Int Bool) = ["exp", "exp1", ...],express names (undefined :: Maybe Int) = ["mx", "mx1", "mx2", ...] nemes (undefined :: Maybe Bool) = ["mp", "mp1", "mp2", ...]-express names (undefined :: ()->()) = ["f", "g", "h", "f'", ...] names (undefined :: Int->Int) = ["f", "g", "h", ...].express name (undefined :: Double) = "x" names (undefined :: Double) = ["x", "y", "z", "x'", ...]/express name (undefined :: Float) = "x" names (undefined :: Float) = ["x", "y", "z", "x'", ...]0express name (undefined :: Complex) = "x" names (undefined :: Complex) = ["x", "y", "z", "x'", ...]1express name (undefined :: Rational) = "q" names (undefined :: Rational) = ["q", "r", "s", "q'", ...]2express name (undefined :: Ordering) = "o" names (undefined :: Ordering) = ["o", "p", "q", "o'", ...]3express name (undefined :: Char) = "c" names (undefined :: Char) = ["c", "d", "e", "c'", "d'", ...]4express name (undefined :: Integer) = "x" names (undefined :: Integer) = ["x", "y", "z", "x'", ...]5express name (undefined :: Int) = "x" names (undefined :: Int) = ["x", "y", "z", "x'", "y'", ...]6express name (undefined :: Bool) = "p" names (undefined :: Bool) = ["p", "q", "r", "p'", "q'", ...]7express name (undefined :: ()) = "u" names (undefined :: ()) = ["u", "v", "w", "u'", "v'", ...](c) 2019-2021 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela None3 :express Encodes a  as a 1. This is useful when generating error messages. > showJustName ''Int "Int"  > showJustName ''String "String" > showJustName ''Maybe "Maybe"?expressNormalizes a type by applying it to necessary type variables making it accept zero type parameters. The normalized type is paired with a list of necessary type variables. > putStrLn $(stringE . show =<< normalizeType ''Int) (ConT ''Int, []) > putStrLn $(stringE . show =<< normalizeType ''Maybe) (AppT (ConT ''Maybe) (VarT ''a),[VarT ''a]) > putStrLn $(stringE . show =<< normalizeType ''Either) (AppT (AppT (ConT ''Either) (VarT ''a)) (VarT ''b),[VarT ''a,VarT ''b]) > putStrLn $(stringE . show =<< normalizeType ''[]) (AppT (ConT ''[]) (VarT a),[VarT a])@expressNormalizes a type by applying it to units to make it star-kinded. (cf. ?)AexpressGiven a type name and a class name, returns whether the type is an instance of that class. The given type must be star-kinded ( * +) and the given class double-star-kinded ( * -> * . > putStrLn $(stringE . show =<< ''Int `isInstanceOf` ''Num) True > putStrLn $(stringE . show =<< ''Int `isInstanceOf` ''Fractional) FalseBexpressThe negation of A.CexpressGiven a type name, return the number of arguments taken by that type. Examples in partially broken TH: 2> putStrLn $(stringE . show =<< typeArity ''Int) 0 4> putStrLn $(stringE . show =<< typeArity ''Maybe) 1 5> putStrLn $(stringE . show =<< typeArity ''Either) 2 1> putStrLn $(stringE . show =<< typeArity ''[]) 1 2> putStrLn $(stringE . show =<< typeArity ''(,)) 2 3> putStrLn $(stringE . show =<< typeArity ''(,,)) 3 5> putStrLn $(stringE . show =<< typeArity ''String) 0This works for Data's and Newtype's and it is useful when generating typeclass instances.Dexpress Given a type *, returns a list of its type constructor s paired with the type arguments they take. the type arguments they take. > putStrLn $(stringE . show =<< typeConstructors ''Bool) [ ('False, []) , ('True, []) ] > putStrLn $(stringE . show =<< typeConstructors ''[]) [ ('[], []) , ('(:), [VarT ''a, AppT ListT (VarT ''a)]) ] > putStrLn $(stringE . show =<< typeConstructors ''(,)) [('(,), [VarT (mkName "a"), VarT (mkName "b")])] > data Point = Pt Int Int > putStrLn $(stringE . show =<< typeConstructors ''Point) [('Pt,[ConT ''Int, ConT ''Int])]Eexpress Is the given  a type synonym? :> putStrLn $(stringE . show =<< isTypeSynonym 'show) False ;> putStrLn $(stringE . show =<< isTypeSynonym ''Char) False <> putStrLn $(stringE . show =<< isTypeSynonym ''String) TrueFexpressResolves a type synonym. > putStrLn $(stringE . show =<< typeSynonymType ''String) AppT ListT (ConT ''Char)MexpressLookups the name of a value throwing an error when it is not found. 8> putStrLn $(stringE . show =<< lookupValN "show") 'showNexpressLists all unbound variables in a type. This intentionally excludes the  constructor.Oexpress$Binds all unbound variables using a  constructor. (cf. N)Pexpress"Same as toBounded but lifted over  89:;<=>?@ABCDEFGHIJKLMNOP;89<=>?@ABCDEFIJM:LGHKNOP(c) 2019-2021 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela None;Qexpress Derives a  instance for the given type .This function needs the TemplateHaskell extension.RexpressSame as Q4 but does not warn when instance already exists (Q is preferable).Sexpress Derives a  instance for a given type 3 cascading derivation of type arguments as well.QRSQSR(c) 2016-2021 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-InferredKTexpress Compares two  s.Different versions of Typeable/GHC provide different orderings for  s. The following is a version independent ordering, with the following properties:0functional types with more arguments are larger;1type constructors with more arguments are larger. > typeOf (undefined :: Int -> Int) `compareTy` typeOf (undefined :: () -> () -> ()) LT > typeOf (undefined :: Int) `compareTy` typeOf (undefined :: ()) GTUexpress*Returns the functional arity of the given  . '> tyArity $ typeOf (undefined :: Int) 0 .> tyArity $ typeOf (undefined :: Int -> Int) 1 -> tyArity $ typeOf (undefined :: (Int,Int)) 0Vexpress.Returns the ultimate result type of the given  . /> finalResultTy (typeOf (undefined :: Int)) Int 8> finalResultTy (typeOf (undefined :: Int -> Char)) Char > finalResultTy (typeOf (undefined :: Int -> Char -> Bool)) BoolWexpressDeconstructs a functional   into a pair of  s. > unFunTy $ typeOf (undefined :: Int -> Char -> Bool) (Int,Char -> Bool)6This function raises an error on non-functional types.(cf. X and Y)XexpressReturns the argument   of a given functional  . 2argumentTy $ typeOf (undefined :: Int -> Char) Int6This function raises an error on non-functional types.(cf. Y)YexpressReturns the result   of a given functional  . 3> resultTy $ typeOf (undefined :: Int -> Char) Char > resultTy $ typeOf (undefined :: Int -> Char -> Bool) Char -> Bool6This function raises an error on non-functional types.(cf. X and V)ZexpressThis 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 type[expressThe   type encoded as a  .\expressThe   type encoded as a  .]expressThe   type encoded as a  .^express#The function type constructor as a  _expressReturns whether a   is functional. > isFunTy $ typeOf (undefined :: Int -> Int) True > isFunTy $ typeOf (undefined :: Int) False`express.Return the number of outer list nestings in a   +> countListTy $ typeOf (undefined :: Int) 0 .> countListTy $ typeOf (undefined :: [Bool]) 1 .> countListTy $ typeOf (undefined :: [[()]]) 2 .> countListTy $ typeOf (undefined :: String) 1 6> countListTy $ typeOf (undefined :: ([Int],[Bool])) 0aexpressConstructs a comparison type ( a -> a -> Bool ") from the given argument type. ?> mkComparisonTy $ typeOf (undefined :: Int) Int -> Int -> Bool <> mkComparisonTy $ typeOf (undefined :: ()) () -> () -> BoolbexpressConstructs a "compare" type ( a -> a -> Ordering ") from the given argument type. > mkCompareTy $ typeOf (undefined :: Int) Int -> Int -> Ordering => mkCompareTy $ typeOf (undefined :: ()) () -> () -> OrderingcexpressO(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 ] > typesIn $ typeOf (undefined :: Int -> [Int] -> [Int]) [ Int , [Int] , [Int] -> [Int] , Int -> [Int] -> [Int] ] > typesIn $ typeOf (undefined :: Maybe Bool) [ Bool , Maybe Bool ]dexpress2Returns types and subtypes from the given list of  s. > typesInList [typeOf (undefined :: () -> Int), typeOf (undefined :: String -> String -> Bool)] [(),Bool,Char,Int,[Char],() -> Int,[Char] -> Bool,[Char] -> [Char] -> Bool] > typesInList [typeOf (undefined :: (Char,Int))] [Char,Int,(Char,Int)]eexpressAn infix alias for  . It is right associative.6 TUVWXYZ[\]^_`abcdeUW_XYV[\]ab^TZcd`ee9 (c) 2019-2021 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-InferredU-fexpressValues of type f represent objects or applications between objects. Each object is encapsulated together with its type and string representation. Values encoded in fs are always monomorphic.An f can be constructed using:j, for values that are   instances;i, for values that are not   instances, like functions;h, for applications between fs. > val False False :: Bool 0> value "not" not :$ val False not False :: BoolAn f can be evaluated using s, t or u. > evl $ val (1 :: Int) :: Int 1 1> evaluate $ val (1 :: Int) :: Maybe Bool Nothing > eval 'a' (val 'b') 'b' ing a value of type f will return a pretty-printed representation of the expression together with its type. 9> show (value "not" not :$ val False) "not False :: Bool"f is like  2 but has support for applications and variables (h, l).The l underscore convention: Functions that manipulate f)s usually follow the convention where a i whose  representation starts with '_' represents a liable.gexpressa i enconded as  and  hexpress(function application between expressionsiexpressO(1). It takes a string representation of a value and a value, returning an f- with that terminal value. For instances of  , it is preferable to use j. '> 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 > value "(+)" ((+) :: Int -> Int -> Int) (+) :: Int -> Int -> Int > value "sort" (sort :: [Bool] -> [Bool]) sort :: [Bool] -> [Bool]jexpressO(1). A shorthand for i for values that are   instances. > val (0 :: Int) 0 :: Int > val 'a' 'a' :: Char > val True True :: BoolExample equivalences to i: val 0 = value "0" 0 val 'a' = value "'a'" 'a' val True = value "True" TruekexpressO(n). Creates an f' representing a function application.  an f! application if the types match,  otherwise. (cf. h) :> value "id" (id :: () -> ()) $$ val () Just (id () :: ()) > 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 () NothinglexpressO(1). Creates an f 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 i6 whose string representation starts with underscore ('_').mexpressO(n). Computes the type of an expression. This raises errors, but this should not happen if expressions are smart-constructed with k. > 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 > 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'nexpressO(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)oexpressO(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) NothingpexpressO(n). Returns whether the given f is ill typed. (cf. q) > 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') TrueqexpressO(n). Returns whether the given f is well typed. (cf. p) +> isWellTyped (absE :$ val (1 :: Int)) True %> isWellTyped (absE :$ val 'b') FalserexpressO(n). Returns whether the given f? is of a functional type. This is the same as checking if the  of the given f is non-zero. .> isFun (value "abs" (abs :: Int -> Int)) True > isFun (val (1::Int)) False > isFun (value "const" (const :: Bool -> Bool -> Bool) :$ val False) TruesexpressO(n). ; the value of an expression when possible (correct type), - otherwise. This does not catch errors from     is. > 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 NothingtexpressO(n). Evaluates an expression when possible (correct type). Returns a default value otherwise. > 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 0uexpressO(n). Evaluates an expression when possible (correct type). Raises an error otherwise. > evl $ two -+- three :: Int 5 > evl $ two -+- three :: Bool *** Exception: evl: cannot evaluate Expr `2 + 3 :: Int' at the Bool type-This may raise errors, please consider using t or s.vexpressO(n)). Evaluates an expression to a terminal   value when possible. Returns  otherwise. <> toDynamic $ val (123 :: Int) :: Maybe Dynamic Just <> > toDynamic $ value "abs" (abs :: Int -> Int) :$ val (-1 :: Int) Just <> > toDynamic $ value "abs" (abs :: Int -> Int) :$ val 'a' NothingwexpressO(n). Like x; but the precedence is taken from the given operator name. *> showOpExpr "*" (two -*- three) "(2 * 3)" (> showOpExpr "+" (two -*- three) "2 * 3"To imply that the surrounding environment is a function application, use " " as the given operator. *> showOpExpr " " (two -*- three) "(2 * 3)"xexpressO(n). Like y2 but allows specifying the surrounding precedence. &> showPrecExpr 6 (one -+- two) "1 + 2" (> showPrecExpr 7 (one -+- two) "(1 + 2)"yexpressO(n). 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 > putStrLn $ showExpr $ (pp -||- true) -&&- (qq -||- false) (p || True) && (q || False)zexpressO(n)". Compares the complexity of two fs. An expression e1 is strictly simpler than another expression e2 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) EQ%This comparison is not a total order.{expressO(n).+ Lexicographical structural comparison of fs where variables < constants < applications then types are compared before string representations. > compareLexicographically one (one -+- one) LT > compareLexicographically one zero GT > compareLexicographically (xx -+- zero) (zero -+- xx) LT > compareLexicographically (zero -+- xx) (zero -+- xx) EQ(cf. T)!This comparison is a total order.|expressO(n). A fast total order between f!s that can be used when sorting f values.&This is lazier than its counterparts z and {" and tries to evaluate the given fs as least as possible.}expressO(n)!. Unfold a function application f( 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 h 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). Check if an f3 has a variable. (By convention, any value whose  representation starts with '_'.) ,> hasVar $ value "not" not :$ val True False > hasVar $ value "&&" (&&) :$ var "p" (undefined :: Bool) :$ val True TrueexpressO(n). Returns whether a f has no$ variables. This is equivalent to " not . hasVar".,The name "ground" comes from term rewriting. -> isGround $ value "not" not :$ val True True > isGround $ value "&&" (&&) :$ var "p" (undefined :: Bool) :$ val True FalseexpressO(1). Returns whether an f is a terminal constant. (cf. ). ,> isConst $ var "x" (undefined :: Int) False > isConst $ val False True .> isConst $ value "not" not :$ val False FalseexpressO(1). Returns whether an f is a terminal variable (l ). (cf. ~). )> isVar $ var "x" (undefined :: Int) True > isVar $ val False False >> isVar $ value "not" not :$ var "p" (undefined :: Bool) FalseexpressO(1). Returns whether an f is a terminal value (g). +> 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 g constructor. Properties:  isValue (Value e) = True  isValue (e1 :$ e2) = False  isValue = not . isApp # isValue e = isVar e || isConst eexpressO(1). Returns whether an f is an application (h). *> 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 h constructor. Properties:  isApp (e1 :$ e2) = True  isApp (Value e) = False  isApp = not . isValue - isApp e = not (isVar e) && not (isConst e)expressO(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. ) > 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 ]expressO(n^3) for full evaluation. Lists all subexpressions of a given expression without repetitions. This includes the expression itself and partial function applications. (cf. ) > 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 ]Runtime averages to  O(n^2 log n), on evenly distributed expressions such as (f x + g y) + (h z + f w) ; and to O(n^3) on deep expressions such as f (g (h (f (g (h x))))).expressO(n). Lists all terminal values in an expression in order and with repetitions. (cf. ) > values (xx -+- yy) [ (+) :: Int -> Int -> Int , x :: Int , y :: Int ] > values (xx -+- (yy -+- zz)) [ (+) :: Int -> Int -> Int , x :: Int , (+) :: Int -> Int -> Int , y :: Int , z :: Int ] > values (zero -+- (one -*- two)) [ (+) :: Int -> Int -> Int , 0 :: Int , (*) :: Int -> Int -> Int , 1 :: Int , 2 :: Int ] > values (pp -&&- true) [ (&&) :: Bool -> Bool -> Bool , p :: Bool , True :: Bool ]expressO(n^2). Lists all terminal values in an expression without repetitions. (cf. ) > 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 ] > nubValues (pp -&&- pp) [ p :: Bool , (&&) :: Bool -> Bool -> Bool ]Runtime averages to  O(n log n), on evenly distributed expressions such as (f x + g y) + (h z + f w) ; and to O(n^2) on deep expressions such as f (g (h (f (g (h x))))).expressO(n). List terminal constants in an expression in order and with repetitions. (cf. ) 1> consts (xx -+- yy) [ (+) :: Int -> Int -> Int ] > consts (xx -+- (yy -+- zz)) [ (+) :: Int -> Int -> Int , (+) :: Int -> Int -> Int ] > consts (zero -+- (one -*- two)) [ (+) :: Int -> Int -> Int , 0 :: Int , (*) :: Int -> Int -> Int , 1 :: Int , 2 :: Int ] > consts (pp -&&- true) [ (&&) :: Bool -> Bool -> Bool , True :: Bool ]expressO(n^2). List terminal constants in an expression without repetitions. (cf. ) 4> nubConsts (xx -+- yy) [ (+) :: Int -> Int -> Int ] => nubConsts (xx -+- (yy -+- zz)) [ (+) :: Int -> Int -> Int ] > nubConsts (pp -&&- true) [ True :: Bool , (&&) :: Bool -> Bool -> Bool ]Runtime averages to  O(n log n), on evenly distributed expressions such as (f x + g y) + (h z + f w) ; and to O(n^2) on deep expressions such as f (g (h (f (g (h x))))).expressO(n). Lists all variables in an expression in order and with repetitions. (cf. ) *> 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]expressO(n^2). Lists all variables in an expression without repetitions. (cf. ) -> 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]Runtime averages to  O(n log n), on evenly distributed expressions such as (f x + g y) + (h z + f w) ; and to O(n^2) on deep expressions such as f (g (h (f (g (h x))))).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) 0expressO(n). 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) 2expressO(n). Returns the maximum depth of a given expression given by the maximum number of nested function applications. Curried function application is counted  only once, 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) 3Flipping 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)) 3Flipping arguments of applications in subterms may change the result of the function.expressO(n). Does not evaluate values when comparing, but rather uses their representation as strings and their types..This instance works for ill-typed expressions.;Expressions come first when they have smaller complexity (z.) or when they come first lexicographically ({).expressO(n). Does not evaluate values when comparing, but rather uses their representation as strings and their types..This instance works for ill-typed expressions.expressShows fs with their types. 9> show (value "not" not :$ val False) "not False :: Bool"*fghijklmnopqrstuvwxyz{|}~*fghijklstumnovpqr~z{|}ywx(c) 2019-2021 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-Inferred0express!Given two expressions, returns a  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 > (zero -+- one) `match` (xx -+- yy) Just [(y :: Int,1 :: Int),(x :: Int,0 :: Int)] > (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 fs, 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 Given two fs, checks if the first expression encompasses the second expression in terms of variables.0This is equivalent to flipping the arguments of . zero `encompasses` xx = False xx `encompasses` zero = Trueexpress:Checks if any of the subexpressions of the first argument f( is an instance of the second argument f.expressO(n^2). Checks if an f 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-2021 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-Inferred express A trie of fs.In the representation,  matches an App and  f an expression.express An empty .express Constructs a  encoding a single expression.express Merges two s.express Inserts an f into a .express List all f stored in a $ along with their associated values.express Constructs a  form a list of key fs and associated values.express*Maps a function to the stored values in a .expressPerforms a lookup in a .   (c) 2019-2021 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-InferredVexpressO(n*m). 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 > 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). 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 > 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 > let pluswap (o :$ xx :$ yy) | o == plus = Just $ o :$ yy :$ xx | pluswap _ = NothingThen: > mapSubexprs pluswap $ (xx -*- yy) -+- (yy -*- zz) y * z + x * y :: Int > mapSubexprs pluswap $ (xx -+- yy) -*- (yy -+- zz) (y + x) * (z + y) :: IntSubstitutions do not stack, in other words a replaced expression or its subexpressions are not further replaced: > 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). 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: > ((xx -+- yy) -+- (yy -+- zz)) //- [(xx, yy), (zz, yy)] (y + y) + (y + y) :: Int > ((xx -+- yy) -+- (yy -+- zz)) //- [(yy, yy -+- zz)] (x + (y + z)) + ((y + z) + z) :: IntThis 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: > ((xx -+- yy) -+- (yy -+- zz)) // [(xx -+- yy, yy), (yy -+- zz, yy)] y + y :: Int > ((xx -+- yy) -+- zz) // [(xx -+- yy, zz), (zz, xx -+- yy)] z + (x + y) :: IntReplacement 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 f. 2> renameVarsBy (++ "'") (xx -+- yy) x' + y' :: Int > 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-2021 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-Inferredǒ expressO(1) . Creates a l&iable with the same type as the given f. 9> let one = val (1::Int) > "x" `varAsTypeOf` one x :: Int '> "p" `varAsTypeOf` val False p :: BoolexpressO(1). Creates an f7 representing a typed hole with the type of the given f. (cf. ) >> val (1::Int) 1 :: Int > holeAsTypeOf $ val (1::Int) _ :: IntexpressO(1). Creates an f6 representing a typed hole of the given argument type. "> hole (undefined :: Int) _ :: Int 4> hole (undefined :: Maybe String) _ :: Maybe [Char]A 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 f represents a typed hole. (cf. ) '> isHole $ hole (undefined :: Int) True ,> isHole $ value "not" not :$ val True False > isHole $ val 'a' FalseexpressO(n). Lists all holes in an expression, in order and with repetitions. (cf. ) .> holes $ hole (undefined :: Bool) [_ :: Bool] > holes $ value "&&" (&&) :$ hole (undefined :: Bool) :$ hole (undefined :: Bool) [_ :: Bool,_ :: Bool] > holes $ hole (undefined :: Bool->Bool) :$ hole (undefined::Bool) [_ :: Bool -> Bool,_ :: Bool]expressO(n^2)?. Lists all holes in an expression without repetitions. (cf. ) 1> nubHoles $ hole (undefined :: Bool) [_ :: Bool] > nubHoles $ value "&&" (&&) :$ hole (undefined :: Bool) :$ hole (undefined :: Bool) [_ :: Bool] > nubHoles $ hole (undefined :: Bool->Bool) :$ hole (undefined::Bool) [_ :: Bool,_ :: Bool -> Bool]Runtime averages to  O(n log n), on evenly distributed expressions such as (f x + g y) + (h z + f w) ; and to O(n^2) on deep expressions such as f (g (h (f (g (h x))))).expressO(n)0. Returns whether an expression contains a hole )> hasHole $ hole (undefined :: Bool) True -> hasHole $ value "not" not :$ val True False <> hasHole $ value "not" not :$ hole (undefined :: Bool) TrueexpressO(n). Returns whether an expression is complete. A complete expression is one without holes. -> isComplete $ hole (undefined :: Bool) False /> isComplete $ value "not" not :$ val True True > isComplete $ value "not" not :$ hole (undefined :: Bool) False is the negation of . isComplete = not . hasHole is to  what  is to ~.expressGenerate 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 , ... ]expressGenerate an infinite list of variables based on a template and the type of a given f. (cf. ) > let one = val (1::Int) > putL 10 $ "x" `listVarsAsTypeOf` one [ x :: Int , y :: Int , z :: Int , x' :: Int , ... ] > let false = val False > putL 10 $ "p" `listVarsAsTypeOf` false [ p :: Bool , q :: Bool , r :: Bool , p' :: Bool , ... ]express0Fill holes in an expression with the given list. > let i_ = hole (undefined :: Int) > let e1 -+- e2 = value "+" ((+) :: Int -> Int -> Int) :$ e1 :$ e2 > let xx = var "x" (undefined :: Int) > let yy = var "y" (undefined :: Int) (> fill (i_ -+- i_) [xx, yy] x + y :: Int (> fill (i_ -+- i_) [xx, xx] x + x :: Int > let one = val (1::Int) 8> fill (i_ -+- i_) [one, one -+- one] 1 + (1 + 1) :: Int-This function silently remaining expressions: > fill i_ [xx, yy] x :: Int-This function silently keeps remaining holes: 5> fill (i_ -+- i_ -+- i_) [xx, yy] (x + y) + _ :: IntThis function silently skips remaining holes if one is not of the right type: >> fill (i_ -+- i_ -+- i_) [xx, val 'c', yy] (x + _) + _ :: Int   (c) 2019-2021 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-InferredexpressO(n). Folds a list of f with function application (h ). This reverses the effect of }. 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 h 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 f values into a single f. (cf. )This always generates an ill-typed expression, as it uses a fake pair constructor. > foldPair (val False, val (1::Int)) (False,1) :: ill-typed # ExprPair $ Bool # > foldPair (val (0::Int), val True) (0,True) :: ill-typed # ExprPair $ Int #9This is useful when applying transformations on pairs of f 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 f3 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(1). Folds a trio/triple of f values into a single f. (cf. )This always generates an ill-typed expression as it uses a fake trio/triple constructor. > foldTrio (val False, val (1::Int), val 'a') (False,1,'a') :: ill-typed # ExprTrio $ Bool # > foldTrio (val (0::Int), val True, val 'b') (0,True,'b') :: ill-typed # ExprTrio $ Int #9This is useful when applying transformations on pairs of f s, such as ,   or . > let ii = var "i" (undefined::Int) > let kk = var "k" (undefined::Int) > let zz = var "z" (undefined::Int) > unfoldPair $ canonicalize $ foldPair (ii,kk,zz) (x :: Int,y :: Int,z :: Int)expressO(1). Unfolds an f: representing a trio/triple. This reverses the effect of . > value ",," ((,,) :: Bool->Bool->Bool->(Bool,Bool,Bool)) :$ val True :$ val False :$ val True (True,False,True) :: (Bool,Bool,Bool) > unfoldTrio $ value ",," ((,,) :: Bool->Bool->Bool->(Bool,Bool,Bool)) :$ val True :$ val False :$ val True (True :: Bool,False :: Bool,True :: Bool)(cf. )expressO(n). Folds a list of fs into a single f. (cf. )This always# generates an ill-typed expression. fold [val False, val True, val (1::Int)] [False,True,1] :: ill-typed # ExprList $ Bool #9This is useful when applying transformations on lists of f 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 f$ representing a list into a list of f 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]}} (c) 2019-2021 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-Inferredexpress typeclass instances provide an  function that allows values to be deeply encoded as applications of fs. expr False = val False expr (Just True) = value "Just" (Just :: Bool -> Maybe Bool) :$ val True The function % can be contrasted with the function j:j! always encodes values as atomic g fs -- shallow encoding.. ideally encodes expressions as applications (h ) between g fs -- 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 expressType restricted version of  that forces its first argument to have the same type as the second. + value -: (undefined :: Ty) = value :: TyexpressType restricted version of  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  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  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-2021 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela Noneexpress 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-2021 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-InferredLfghijklmnopqrstuvwxyz{|}~(c) 2019-2021 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-InferredzexpressO(1). Reifies an   instance into a list of fs. The list will contain   and   for the given type. (cf. , ) > reifyEq (undefined :: Int) [ (==) :: Int -> Int -> Bool , (/=) :: Int -> Int -> Bool ] > reifyEq (undefined :: Bool) [ (==) :: Bool -> Bool -> Bool , (/=) :: Bool -> Bool -> Bool ] > reifyEq (undefined :: String) [ (==) :: [Char] -> [Char] -> Bool , (/=) :: [Char] -> [Char] -> Bool ]expressO(1). Reifies an   instance into a list of fs. The list will contain ,   and   for the given type. (cf. , , , ) > reifyOrd (undefined :: Int) [ (<=) :: Int -> Int -> Bool , (<) :: Int -> Int -> Bool ] > reifyOrd (undefined :: Bool) [ (<=) :: Bool -> Bool -> Bool , (<) :: Bool -> Bool -> Bool ] > reifyOrd (undefined :: [Bool]) [ (<=) :: [Bool] -> [Bool] -> Bool , (<) :: [Bool] -> [Bool] -> Bool ]expressO(1). Reifies   and   instances into a list of f.expressO(1). Reifies a  instance into a list of fs. 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).% Lookups for a comparison function (:: a -> a -> Bool)) with the given name and argument type.expressO(n). Returns whether an  < instance exists in the given instances list for the given  . > isEqT (reifyEqOrd (undefined :: Int)) (typeOf (undefined :: Int)) True > 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  . > isOrdT (reifyEqOrd (undefined :: Int)) (typeOf (undefined :: Int)) True > 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 f. :> isEq (reifyEqOrd (undefined :: Int)) (val (0::Int)) True > isEq (reifyEqOrd (undefined :: Int)) (val ([[[0::Int]]])) False)Given that the instances list has length m and that the given f 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 f. ;> isOrd (reifyEqOrd (undefined :: Int)) (val (0::Int)) True > isOrd (reifyEqOrd (undefined :: Int)) (val ([[[0::Int]]])) False)Given that the instances list has length m and that the given f 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 f.)Given that the instances list has length m and that the given f has size n, this function is O(n+m).expressO(n+m). Like ,  and 0 but allows providing the binary operator name.)When not possible, this function returns   encoded as an f.expressO(n+m). Returns an equation between two expressions given that it is possible to do so from  1 operators given in the argument instances list.)When not possible, this function returns   encoded as an f.expressO(n+m). Returns a less-than inequation between two expressions given that it is possible to do so from  1 operators given in the argument instances list.)When not possible, this function returns   encoded as an f.expressO(n+m). Returns a less-than-or-equal-to inequation between two expressions given that it is possible to do so from  1 operators given in the argument instances list.)When not possible, this function returns   encoded as an f.expressO(n+m). Like ) but lifted over an instance list and an f. 1> lookupName preludeNameInstances (val False) "p" 4> lookupName preludeNameInstances (val (0::Int)) "x"This function defaults to "x" when no appropriate  is found. > lookupName [] (val False) "x"expressO(n+m). A mix between  and : this returns an infinite list of names based on an instances list and an f.expressO(n+m). Like , but returns a list of variables encoded as fs.expressGiven a list of functional expressions and another expression, returns a list of valid applications.expressLike  but returns a  value.expressA list of reified  instances for an arbitrary selection of types from the Haskell Prelude. 1(c) 2019-2021 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-InferredV expressLike  but allows customization of the list of variable names. (cf. , ) > canonicalizeWith (const ["i","j","k","l",...]) (xx -+- yy) i + j :: Int The argument f 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" > 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 f 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: > canonicalize (jj -+- (zero -+- abs' ii)) x + (y + abs y) :: Int'This also works for variable functions: > canonicalize (gg yy -+- ff xx -+- gg xx) (f x + g y) + f y :: Intexpress Return a canonicalization of an f3 that makes variable names appear in order using  as provided by  . By using  it can  fs. > 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) ] > canonicalization (yy -+- xx -+- yy) [ (x :: Int, y :: Int) , (y :: Int, x :: Int) ]expressReturns whether an f is canonical: if applying  is an identity using  as provided by .express'Returns all canonical variations of an f by filling holes with variables. Where possible, variations are listed from most general to least general. %> canonicalVariations $ i_ [x :: Int] > 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] > 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 ]In 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]When applying this to expressions already containing variables clashes are avoided and these variables are not touched: > canonicalVariations $ i_ -+- ii -+- jj -+- i_ [ x + i + j + y :: Int , x + i + j + y :: Int ] 0> canonicalVariations $ ii -+- jj [i + j :: Int] > canonicalVariations $ xx -+- i_ -+- i_ -+- length' (c_ -:- unit c_) -+- yy [ (((x + z) + x') + length (c:d:"")) + y :: Int , (((x + z) + x') + length (c:c:"")) + y :: Int , (((x + z) + z) + length (c:d:"")) + y :: Int , (((x + z) + z) + length (c:c:"")) + y :: Int ]express3Returns the most general canonical variation of an f" by filling holes with variables. -> mostGeneralCanonicalVariation $ i_ x :: Int 8> mostGeneralCanonicalVariation $ i_ -+- i_ x + y :: Int > mostGeneralCanonicalVariation $ i_ -+- i_ -+- i_ (x + y) + z :: Int > mostGeneralCanonicalVariation $ i_ -+- ord' c_ x + ord c :: Int > mostGeneralCanonicalVariation $ i_ -+- i_ -+- ord' c_ (x + y) + ord c :: Int > mostGeneralCanonicalVariation $ i_ -+- i_ -+- length' (c_ -:- unit c_) (x + y) + length (c:d:"") :: IntIn an expression without holes this functions just returns the given expression itself: 9> mostGeneralCanonicalVariation $ val (0 :: Int) 0 :: Int 9> mostGeneralCanonicalVariation $ ord' bee ord 'b' :: Int(This function is the same as taking the  of  but a bit faster.express4Returns the most specific canonical variation of an f" by filling holes with variables. .> mostSpecificCanonicalVariation $ i_ x :: Int 9> mostSpecificCanonicalVariation $ i_ -+- i_ x + x :: Int > mostSpecificCanonicalVariation $ i_ -+- i_ -+- i_ (x + x) + x :: Int > mostSpecificCanonicalVariation $ i_ -+- ord' c_ x + ord c :: Int > mostSpecificCanonicalVariation $ i_ -+- i_ -+- ord' c_ (x + x) + ord c :: Int > mostSpecificCanonicalVariation $ i_ -+- i_ -+- length' (c_ -:- unit c_) (x + x) + length (c:c:"") :: IntIn an expression without holes this functions just returns the given expression itself: :> mostSpecificCanonicalVariation $ val (0 :: Int) 0 :: Int :> mostSpecificCanonicalVariation $ ord' bee ord 'b' :: Int(This function is the same as taking the  of  but a bit faster.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 f% 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: > map canonicalize . fastCanonicalVariations $ i_ -+- ord' c_ [x + ord c :: Int]'This function is useful when resulting fs 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.expressA faster version of  that disregards name clashes across different types. Consider using  instead.The same caveats of  do apply here.expressA faster version of  that disregards name clashes across different types. Consider using  instead.The same caveats of  do apply here.  (c) 2019-2021 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela NoneQRSfghijklmnopqrstuvwxyz{|}~fghijklstumnovpqr~z{|yxw}QSR(c) 2019-2021 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela Nonei̢expressf representing a hole of   type. > b_ _ :: Boolexpressf representing a variable p ::  . > pp p :: Boolexpressf representing a variable q ::  . > qq q :: Boolexpressf representing a variable r ::  . > rr r :: Boolexpressf representing a variable p' ::  . > pp' p' :: Boolexpress  encoded as an f. > false False :: Boolexpress  encoded as an f. > true True :: Boolexpress The function   encoded as an f. > notE not :: Bool -> Boolexpress The function  encoded as an f. #> andE (&&) :: Bool -> Bool -> Boolexpress The function  encoded as an f. "> orE (||) :: Bool -> Bool -> Boolexpress The function ==> lifted over fs. )> false -==>- true False ==> True :: Bool %> evl $ false -==>- true :: Bool TrueexpressThe ==> operator encoded as an fexpress The function   lifted over the f type. > not' false not False :: Bool > evalBool $ not' false True > not' pp not p :: Boolexpress The function   lifted over the f type. > pp -&&- qq p && q :: Bool '> false -&&- true False && True :: Bool "> evalBool $ false -&&- true Falseexpress The function   lifted over the f 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 A variable i of   type.  > ii i :: Intexpress A variable j of   type.  > jj j :: Intexpress A variable k of   type.  > kk k :: Intexpress A variable i' of   type. > ii' i' :: Intexpress A variable l of   type.  > ll l :: Intexpress A variable m of   type.  > mm m :: Intexpress A variable n of   type.  > nn n :: Intexpress The value 0 bound to the   type encoded as an f. > zero 0 :: Intexpress The value 1 bound to the   type encoded as an f. > one 1 :: Intexpress The value 2 bound to the   type encoded as an f. > two 2 :: Intexpress The value 3 bound to the   type encoded as an f. > three 3 :: Intexpress The value 4 bound to the   type encoded as an f. > four 4 :: Intexpress The value 5 bound to the   type encoded as an f. > five 5 :: Intexpress The value 6 bound to the   type encoded as an f. > six 6 :: Intexpress The value 7 bound to the   type encoded as an f. > seven 7 :: Intexpress The value 8 bound to the   type encoded as an f. > eight 8 :: Intexpress The value 9 bound to the   type encoded as an f. > nine 9 :: Intexpress The value 10 bound to the   type encoded as an f. > ten 10 :: Intexpress The value 11 bound to the   type encoded as an f. > eleven 11 :: Intexpress The value 12 bound to the   type encoded as an f. > twelve 12 :: Intexpress The value -1 bound to the   type encoded as an f. > minusOne -1 :: Intexpress The value -2 bound to the   type encoded as an f. > minusOne -2 :: IntexpressA variable function f& of 'Int -> Int' type lifted over the f type. > ff xx f x :: Int > ff one f 1 :: Intexpress A variable f$ of 'Int -> Int' type encoded as an f. > ffE f :: Int -> IntexpressA variable function g& of 'Int -> Int' type lifted over the f type. > gg yy g y :: Int > gg minusTwo gg (-2) :: Intexpress A variable g$ of 'Int -> Int' type encoded as an f. > ggE g :: Int -> IntexpressA variable function h& of 'Int -> Int' type lifted over the f type. > hh zz h z :: Intexpress A variable h$ of 'Int -> Int' type encoded as an f. > hhE h :: Int -> IntexpressA variable binary operator ? lifted over the f type. Works for  ,  , , [Int] and . > xx -?- yy x ? y :: Int > pp -?- qq p ? q :: Bool > xx -?- qq *** Exception: (-?-): cannot apply `(?) :: * -> * -> *` to `x :: Int' and `q :: Bool'. Unhandled types?expressA variable binary operator ? encoded as an f (cf. ) #> question :$ xx :$ yy x ? y :: Int $> question :$ pp :$ qq p ? q :: BoolexpressA variable binary operator o lifted over the f type. Works for  ,  , , [Int] and . > xx `oo` yy x `o` y :: Int > pp `oo` qq p `o` q :: Bool > xx `oo` qq *** Exception: (-?-): cannot apply `o :: * -> * -> *` to `x :: Int' and `q :: Bool'. Unhandled types?expressA variable binary function o encoded as an f (cf. )  > ooE :$ xx :$ yy x `o` y :: Int !> ooE :$ pp :$ qq p `o` q :: Boolexpress The operator   for the   type for use on fs. (See also .) > two -+- three 2 + 3 :: Int 9> minusOne -+- minusTwo -+- zero ((-1) + (-2)) + 0 :: Int '> xx -+- (yy -+- zz) x + (y + z) :: Intexpress The operator   for the   type. (See also .) > plus (+) :: Int -> Int -> Int !> plus :$ one (1 +) :: Int -> Int > plus :$ xx :$ yy x + y :: Intexpress The operator   for the   type lifted over the f type. (See also .) > three -*- three 3 * 3 :: Int *> one -*- two -*- three (1 * 2) * 3 :: Int > two -*- xx 2 * x :: Intexpress The operator   for the   type. (See also .)  > times (*) :: Int -> Int -> Int "> times :$ two (2 *) :: Int -> Int  > times :$ xx :$ yy x * y :: IntexpressThe subtraction   operator encoded as an f. "> minus :$ one (1 -) :: Int -> Int #> minus :$ one :$ zero 1 - 0 :: Intexpress The function   for the   type lifted over the f type. (See also  .) "> six `div'` four 6 `div` 4 :: IntexpressInteger division   encoded as an f. %> divE :$ two (2 `div`) :: Int -> Int '> divE :$ two :$ three 2 `div` 3 :: Intexpress The function   for the   type lifted over the f type. (See also  .) "> six `mod'` four 6 `mod` 4 :: IntexpressInteger modulo   encoded as an f. %> modE :$ two (2 `mod`) :: Int -> Int '> modE :$ two :$ three 2 `mod` 3 :: Intexpress The function   for the   type lifted over the f type. (See also  .) $> six `quot'` four 6 `quot` 4 :: IntexpressInteger quotient   encoded as an f. '> quotE :$ two (2 `quot`) :: Int -> Int )> quotE :$ two :$ three 2 `quot` 3 :: Intexpress The function   for the   type lifted over the f type. (See also  .) "> six `rem'` four 6 `rem` 4 :: IntexpressInteger remainder   encoded as an f. %> remE :$ two (2 `rem`) :: Int -> Int '> remE :$ two :$ three 2 `rem` 3 :: IntexpressConstructs an application of  as an f. 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 f . (See also .) > idE :$ xx id x :: Int > idE :$ zero id 0 :: Int ,> evaluate $ idE :$ zero :: Maybe Int Just 0express The function  encoded as an f. (cf. )express The function  encoded as an f. (cf. )express The function  encoded as an f. (cf. )express The function  encoded as an f. (cf. )express The function  encoded as an f. (cf. )express The function  encoded as an f. (cf. )expressThe  function lifted over the f type. "> const' zero one const 0 1 :: Int"This works for the argument types  , ,   and their lists.express  over the   type lifted over the f type. > negate' xx negate x :: Int > evl (negate' one) :: Int -1express  over the   type encoded as an f > negateE negate :: Int -> Intexpress  over the   type lifted over the f type. > abs' xx' abs x' :: Int > evl (abs' minusTwo) :: Int 2express  over the   type encoded as an f. > absE abs :: Int -> Intexpress  over the   type lifted over the f type. > signum' xx' signum x' :: Int "> evl (signum' minusTwo) :: Int -1express  over the   type encoded as an f. > signumE signum :: Int -> Intexpress  with an   argument lifted over the f type. '> odd' (xx -+- one) odd (x + 1) :: Bool > evl (odd' two) :: Bool Falseexpress  with an   argument lifted over the f type. )> even' (xx -+- two) even (x + 2) :: Bool > evl (even' two) :: Bool Trueexpress A hole of  type encoded as an f. > c_ _ :: Charexpress A hole of  type encoded as an f. > cs_ _ :: [Char]expressA variable named c of type  encoded as an f. > cc c :: CharexpressA variable named c of type  encoded as an f. > dd d :: CharexpressA variable named cs of type  encoded as an f. > ccs cs :: [Char]expressThe character 'a' encoded as an f. > ae 'a' :: Char > evl ae :: Char 'a'expressThe character 'b' encoded as an f > bee 'b' :: Char > evl bee :: Char 'b'expressThe character 'c' encoded as an f > cee 'c' :: Char > evl cee :: Char 'c'expressThe character 'd' encoded as an f > dee 'd' :: Char > evl dee :: Char 'd'expressThe character 'z' encoded as an f > zed 'z' :: Char > evl zed :: Char 'z'(cf. )expressThe character 'z' encoded as an f > zee 'z' :: Char > evl zee :: Char 'z'(cf. )express"The space character encoded as an f > space ' ' :: Charexpress'The line break character encoded as an f > lineBreak '\n' :: CharexpressThe  function lifted over f > ord' bee ord 'b' :: Int > evl (ord' bee) 98expressThe  function encoded as an fexpressA typed hole of [Int] type encoded as an f. > is_ _ :: [Int]expressA variable named xs of type [Int] encoded as an f. > xxs xs :: [Int]expressA variable named ys of type [Int] encoded as an f. > yys ys :: [Int]expressA variable named zs of type [Int] encoded as an f. > yys ys :: [Int]expressAn empty list of type [Int] encoded as an f. > nil [] :: [Int]express An empty  encoded as an f. > emptyString "" :: Stringexpress"The empty list '[]' encoded as an f.express"The empty list '[]' encoded as an f.express"The empty list '[]' encoded as an f.expressThe list constructor with   as element type encoded as an f. #> cons (:) :: Int -> [Int] -> [Int] !> cons :$ one :$ nil [1] :: [Int]Consider using  and  when building lists of f.expressThe list constructor  :  encoded as an f.expressThe list constructor  :  encoded as an f.expressThe list constructor  :  encoded as an f.express constructs a list with a single element. This works for elements of type  ,  and  . > unit one [1] > unit false [False]express%The list constructor lifted over the f& 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]expressAppend for list of  s encoded as an f.express#List concatenation lifted over the f& type. Works for the element types  ,  and  . > (zero -:- one -:- nil) -:- (two -:- three -:- nil) [0,1] -++- [2,3] :: [Int] 9> (bee -:- unit cee) -:- unit dee "bc" -++- "c" :: [Char]expressList  lifted over the f& 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 1expressList  lifted over the f& 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]expressList  lifted over the f& type. Works for the element types  ,  and  . #> null' $ unit one null [1] :: Bool > null' $ nil null [] :: Bool > evl $ null' nil :: Bool TrueexpressList  lifted over the f& 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 1expressList  lifted over the f& type. Works for the element types  ,  and  . $> init' $ unit one init [1] :: [Int] %> init' $ unit bee init "b" :: [Char] /> init' $ zero -:- unit two init [0,2] :: [Int] .> evl $ init' $ zero -:- unit two :: [Int] [0]expressList  lifted over the f& type. Works for the element types  ,  and  . "> sort' $ unit one sort [1] :: Int "> sort' $ unit bee sort "b" :: Int -> sort' $ zero -:- unit two sort [0,2] :: Int /> evl $ sort' $ two -:- unit one :: [Int] [1,2]expressList  lifted over the f& type. Works for the element types  ,  and  . *> insert' zero nilInt insert 0 [] :: [Int] > insert' false (false -:- unit true) insert False [False,True] :: [Bool]expressList  lifted over the f& type. Works for the element types  ,  and  . > elem' false (false -:- unit true) elem False [False,True] :: Bool 6> evl $ elem' false (false -:- unit true) :: Bool Trueexpress lifted over fs > absE -$- one abs $ 1 :: Int Works for  ,  ,  argument types and their lists.express#Constructs an equation between two fs. > xx -==- zero x == 0 :: Bool > cc -==- dee c == 'd' :: BoolThis works for the  ,  ,  argument types and their lists.express%Constructs an inequation between two fs. > xx -/=- zero x /= 0 :: Bool > cc -/=- ae c /= 'a' :: Boolexpress7Constructs a less-than-or-equal inequation between two fs. > xx -<=- zero x <= 0 :: Bool > cc -<=- ae c <= 'a' :: Boolexpress.Constructs a less-than inequation between two fs. > xx -<- zero x < 0 :: Bool > cc -<- bee c < 'b' :: BoolexpressA virtual function if :: Bool -> a -> a -> a lifted over the f/ type. This is displayed as an if-then-else. ,> if' pp zero xx (if p then 0 else x) :: Int 5> zz -*- if' pp xx yy z * (if p then x else y) :: Int > if' pp false true -||- if' qq true false (if p then False else True) || (if q then True else False) :: Bool 0> evl $ if' true (val 't') (val 'f') :: Char 't'expressConstructs an f -encoded  operation between two fs. ,> xx `compare'` zero compare x 0 :: Ordering -> compare' ae bee compare 'a' 'b' :: Orderingexpress bound to the    type encoded as an f.This is an alias to .express bound to the    type encoded as an f.express bound to the    type encoded as an f.expressThe  constructor of the   element type encoded as an f.expressThe  constructor of the   element type encoded as an f.expressThe  constructor lifted over the f type.This works for the   and   argument types. > just zero Just 0 :: Maybe Int > just false Just False :: Maybe BoolexpressAn infix synonym of .express!The pair constructor lifted over fs.This works for the   and  $ element types by differently from & by returning a well-typed expression.expressThe pair constructor ( :: ... -> (Int,Int) ) encoded as an f.express(The triple/trio constructor lifted over fs.This only works for the   element type.express&The quadruple constructor lifted over fs.This only works for the   element type.express&The quintuple constructor lifted over fs.This only works for the   element type.express%The sixtuple constructor lifted over fs.This only works for the   element type.expressA typed hole of [Bool] type encoded as an f. > bs_ _ :: [Bool]expressf representing a variable p' :: `[Bool]`. > pps ps :: [Bool]expressA typed hole of '[Bool]' type > qqs qs :: [Bool]express lifted over the f type. > and' pps and ps :: Bool .> evl (and' $ expr [False,True]) :: Bool Falseexpress lifted over the f type. > or' pps or ps :: Bool ,> evl (or' $ expr [False,True]) :: Bool Trueexpress of   elements lifted over the f type. > sum' xxs sum xs :: Int )> evl (sum' $ expr [1,2,3::Int]) :: Int 6express of   elements lifted over the f type.  > product' xxs product xs :: Int -> evl (product' $ expr [1,2,3::Int]) :: Int 6expressThe   constructor lifted over fs. > val (2 :: Integer) -%- val (3 :: Integer) 2 % 3 :: Ratio IntegerThis only accepts fs bound to the   type.express#Function composition encoded as an f: ;> compose (.) :: (Int -> Int) -> (Int -> Int) -> Int -> IntexpressFunction composition  lifted over f. -> absE -.- negateE abs . negate :: Int -> Int 1> absE -.- negateE :$ one (abs . negate) 1 :: IntThis works for  ,  ,  and their lists.express over the   element type encoded as an f ,> mapE map :: (Int -> Int) -> [Int] -> [Int]express lifted over fs. +> map' absE (unit one) map abs [1] :: [Int]express  lifted over fs. $> enumFrom' zero enumFrom 0 :: [Int] Works for  s,  s and s.express  lifted over f s named as ".." for pretty-printing. > (-..) one [1..] :: [Int] Works for  s,  s and s.express  lifted over fs /> enumFromTo' zero four enumFromTo 0 4 :: [Int]express  lifted over fs but named as ".." for pretty-printing.  > zero -..- four [0..4] :: [Int]express  lifted over fs 3> enumFromThen' zero ten enumFromThen 0 10 :: [Int]express  lifted over fs but named as ",.." for pretty printing. !> zero -... ten [0,10..] :: [Int]express  lifted over fs. => enumFromThenTo' zero two ten enumFromThenTo 0 2 10 :: [Int]express  lifted over fs but named as ",.." for pretty-printing. )> (zero -...- two) ten [0,2..10] :: [Int]QRSfghijklmnopqrstuvwxyz{|}~ 032675564444  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~Z                                                                                       +                                                                                                                                                                                                                                                                                                                                                                                                  #express-1.0.8-I8jW3dTTzJZz0OlDpoBPIData.Express.Utils.ListData.Express.Utils.StringData.Express.NameData.Express.Utils.THData.Express.Name.DeriveData.Express.Utils.TypeableData.Express.CoreData.Express.MatchData.Express.TriexprData.Express.MapData.Express.HoleData.Express.FoldData.Express.ExpressData.Express.Express.DeriveData.Express.InstancesData.Express.CanonData.Express.FixturesData.Express.Utils canonicalize mapValuescanonicalVariations deriveExpressData.Express.Basic Data.ExpressnubSort nubSortBy isSubsetOfisPermutationOfisNublookupId+++unquoteatomicouternmostPrecisNegativeLiteralisInfixprecisPrefixisInfixedPrefixtoPrefix primeCyclevariableNamesFromTemplateNamenamenames$fName(,,,,,,,,,,,)$fName(,,,,,,,,,,)$fName(,,,,,,,,,)$fName(,,,,,,,,)$fName(,,,,,,,)$fName(,,,,,,) $fName(,,,,,) $fName(,,,,)$fNameGeneralCategory $fNameWord64 $fNameWord32 $fNameWord16 $fNameWord8 $fNameInt64 $fNameInt32 $fNameInt16 $fNameInt8 $fNameWord$fName[] $fName(,,,) $fName(,,) $fName(,) $fNameEither $fNameMaybe$fName-> $fNameDouble $fNameFloat $fNameComplex $fNameRatio$fNameOrdering $fNameChar $fNameInteger $fNameInt $fNameBool$fName()deriveWhenNeededderiveWhenNeededOrWarn showJustNamereallyDeriveCascading typeConArgstypeConArgsThattypeConCascadingArgsThat normalizeTypenormalizeTypeUnits isInstanceOfisntInstanceOf typeAritytypeConstructors isTypeSynonymtypeSynonymType|=>||++| mergeIFnsmergeIwhereItypeConstructorsArgNames lookupValN unboundVars toBounded toBoundedQ deriveNamederiveNameIfNeededderiveNameCascading compareTytyArity finalResultTyunFunTy argumentTyresultTy elementTyboolTyintTy orderingTyfunTyConisFunTy countListTymkComparisonTy mkCompareTytypesIn typesInList->::ExprValue:$valueval$$vartypetypmtyp isIllTyped isWellTypedisFunevaluateevalevl toDynamic showOpExpr showPrecExprshowExprcompareComplexitycompareLexicographicallycompareQuickly unfoldApphasVarisGroundisConstisVarisValueisAppsubexprs nubSubexprsvalues nubValuesconsts nubConstsvarsnubVarsaritysizedepthheight $fOrdExpr$fEqExpr $fShowExprmatch matchWith encompasses hasInstanceOf isSubexprOfTriexpremptyunitmergeinserttoListfromListmaplookup $fEqTriexpr $fOrdTriexpr $fShowTriexprmapVars mapConsts mapSubexprs//-// renameVarsBy varAsTypeOf holeAsTypeOfholeisHoleholesnubHoleshasHole isCompletelistVarslistVarsAsTypeOffillfoldAppfoldPair unfoldPairfoldTrio unfoldTriofoldunfoldExpressexpr-:->:->>:->>>:->>>>:->>>>>:->>>>>>: ->>>>>>>: ->>>>>>>>: ->>>>>>>>>: ->>>>>>>>>>: ->>>>>>>>>>>:->>>>>>>>>>>>:$fExpressGeneralCategory$fExpressWord64$fExpressWord32$fExpressWord16$fExpressWord8 $fExpressWord$fExpressInt64$fExpressInt32$fExpressInt16 $fExpressInt8$fExpressFloat$fExpressDouble$fExpress(,,,,,,,,,,,)$fExpress(,,,,,,,,,,)$fExpress(,,,,,,,,,)$fExpress(,,,,,,,,)$fExpress(,,,,,,,)$fExpress(,,,,,,)$fExpress(,,,,,)$fExpress(,,,,)$fExpressComplex$fExpressRatio $fExpress[]$fExpress(,,,) $fExpress(,,) $fExpress(,)$fExpressEither$fExpressMaybe$fExpressOrdering $fExpressChar$fExpressInteger $fExpressInt $fExpressBool $fExpress()deriveExpressIfNeededderiveExpressCascadingreifyEqreifyOrd reifyEqOrd reifyNamemkEqmkOrdmkOrdLessEqualmkName mkNameWithlookupComparisonisEqTisOrdTisEqOrdTisEqisOrdisEqOrd mkComparison mkEquationmkComparisonLTmkComparisonLE lookupName lookupNames listVarsWith validApps findValidApppreludeNameInstancescanonicalizeWithcanonicalizationWithisCanonicalWithcanonicalization isCanonicalmostGeneralCanonicalVariationmostSpecificCanonicalVariationfastCanonicalVariationsfastMostGeneralVariationfastMostSpecificVariationb_ppqqrrpp'falsetruenotEandEorE-==>-impliesnot'-&&--||-i_xxyyzzxx'iijjkkii'llmmnnzeroonetwothreefourfivesixseveneightnineteneleventwelveminusOneminusTwoffffEggggEhhhhE-?-questionooooE-+-plus-*-timesminusdiv'divEmod'modEquot'quotErem'remEid'idEidIntidBoolidCharidIntsidBoolsidStringconst'negate'negateEabs'absEsignum'signumEodd'even'c_cs_ccddccsaebeeceedeezedzeespace lineBreakord'ordEis_xxsyyszzsnil emptyStringnilIntnilBoolnilCharconsconsIntconsBoolconsChar-:- appendInt-++-head'tail'null'length'init'sort'insert'elem'-$--==--/=--<=--<-if'compare'nothing nothingInt nothingBooljustIntjustBooljust-|-paircommatriple quadruple quintuplesixtuplebs_ppsqqsand'or'sum'product'-%-compose-.-mapEmap' enumFrom'-.. enumFromTo'-..- enumFromThen'-...enumFromThenTo'-...-ghc-prim GHC.ClassescomparebaseGHC.ListGHC.Base++filterzip Data.Foldableelemminimummaximumfoldr1productsumfoldl1foldl'nullfoldlfoldrlength Data.ListisSubsequenceOfData.Traversable mapAccumR mapAccumLfindnotElem minimumBy maximumByallanyorand concatMapconcat Data.OldListunwordswordsunlineslinesunfoldrsortOnsortBysort permutations subsequencestailsinitsgroupBygroupdeleteFirstsByunzip7unzip6unzip5unzip4zipWith7zipWith6zipWith5zipWith4zip7zip6zip5zip4genericReplicate genericIndexgenericSplitAt genericDrop genericTake genericLengthinsertBy partition transpose intercalate intersperse intersectBy intersectunionByunion\\deleteBydeletenubBynub isInfixOf isSuffixOf isPrefixOf findIndices findIndex elemIndices elemIndex stripPrefix dropWhileEndunzip3unzipzipWith3zipWithzip3!!reversebreakspansplitAtdroptake dropWhile takeWhilecycle replicaterepeatiterate'iteratescanr1scanrscanl'scanl1scanlfoldl1'initlasttailunconsheadString GHC.TypesChar Data.Char isSeparatorisNumberisMarkisLetter digitToIntGHC.Read readLitChar lexLitChar GHC.UnicodetoTitletoUppertoLowerisLowerisUpperisPrint isControl isAlphaNumisAlphaisSymbol isPunctuation isHexDigit isOctDigitisDigitisSpace isAsciiUpper isAsciiLowerisLatin1isAsciigeneralCategoryGeneralCategory NotAssigned PrivateUse SurrogateParagraphSeparator LineSeparatorSpace OtherSymbolModifierSymbolCurrencySymbol MathSymbolOtherPunctuation FinalQuote InitialQuoteClosePunctuationOpenPunctuationDashPunctuationConnectorPunctuation OtherNumber LetterNumber DecimalNumber EnclosingMarkSpacingCombiningMarkNonSpacingMark OtherLetterModifierLetterTitlecaseLetterLowercaseLetterUppercaseLetterFormatControlGHC.CharchrGHC.Show intToDigit showLitCharord$ Control.MonadguardjoinMonadreturn>>=>>Functorfmap<$Control.Monad.Fail MonadFailfailmapMsequence<>Monoidmconcatmemptymappend GHC.MaybeMaybeNothingJust Data.EitherEitherLeftRightmfilter<$!>unless replicateM_ replicateMfoldM_foldM zipWithM_zipWithM mapAndUnzipMforever<=<>=>filterMforMmsum sequence_forM_mapM_ Data.MonoidFirstgetFirstLastgetLastApgetApData.Semigroup.InternalDualgetDualEndoappEndoAllgetAllAnygetAnySumgetSumProduct getProductAltgetAlt fromRightfromLeftisRightisLeftpartitionEithersrightsleftseither Data.MaybemapMaybe catMaybes listToMaybe maybeToList fromMaybefromJust isNothingisJustmaybe Data.Function&onfix Data.Functorvoidflip.constidapliftM5liftM4liftM3liftM2liftMwhen=<< MonadPlusmzeromplustemplate-haskellLanguage.Haskell.TH.SyntaxForallTQnewName Language.Haskell.TH.Lib.InternalcharLstringLintegerLintPrimL wordPrimL floatPrimL doublePrimL rationalL stringPrimL charPrimLlitPvarPtupP unboxedTupP unboxedSumPconPinfixPtildePbangPasPwildPrecPlistPsigPviewPfieldPatclausevarEconElitEappEappTypeEinfixEinfixAppsectionLsectionRlamElamCaseE unboxedSumEcondEmultiIfEletEcaseEdoEcompEfromE fromThenEfromToE fromThenToElistEsigErecConErecUpdEstaticE unboundVarElabelEimplicitParamVarEmdoEfieldExpguardedBnormalBnormalGEpatGEbindSletSnoBindSparSrecSfunDvalDinstanceWithOverlapDsigDforImpDpragInlD pragSpecD pragSpecInlD pragSpecInstDpragAnnD tySynInstDinfixLDinfixRDinfixND roleAnnotD defaultSigDpatSynD patSynSigD pragCompleteDimplicitParamBindDkiSigDcxtnoSourceUnpackednesssourceNoUnpack sourceUnpacknoSourceStrictness sourceLazy sourceStrictnormalCrecCinfixCgadtCrecGadtCbangbangType varBangTypeunidir implBidir explBidir prefixPatSyn infixPatSyn recordPatSyn forallVisTvarTconTtupleT unboxedTupleT unboxedSumTarrowTlistTappTappKindT equalityTlitT promotedTpromotedTupleT promotedNilT promotedConsT wildCardTimplicitParamTinfixTnumTyLitstrTyLitnominalRrepresentationalRphantomRinferRvarKconKtupleKarrowKlistKappKinjectivityAnncCallstdCallcApiprim javaScriptunsafesafe interruptiblefunDepruleVar typedRuleVarvalueAnnotationtypeAnnotationmoduleAnnotationExpImplicitParamVarELabelE UnboundVarEStaticERecUpdERecConESigEListE ArithSeqECompEMDoEDoECaseELetEMultiIfECondE UnboxedSumE UnboxedTupETupELamCaseELamEParensEUInfixEInfixEAppTypeEAppELitEVarEConEMatchClauseExpQDecQPatViewPSigPListPRecPWildPAsPBangPTildePParensPUInfixPInfixPConP UnboxedSumP UnboxedTupPTupPLitPVarPMatchQClauseQStmtQConQTypeQTypeImplicitParamT WildCardTLitT ConstraintTStarT PromotedConsT PromotedNilTPromotedTupleTListT EqualityTArrowT UnboxedSumT UnboxedTupleTTupleTParensTUInfixTInfixT PromotedTConTVarTSigTAppKindTAppT ForallVisTDecImplicitParamBindD PatSynSigDPatSynD DefaultSigDStandaloneDerivD RoleAnnotDClosedTypeFamilyDOpenTypeFamilyD TySynInstD NewtypeInstD DataInstD DataFamilyDPragmaDInfixDForeignDKiSigDSigD InstanceDClassDTySynDNewtypeDDataDFunDValD BangTypeQ VarBangTypeQFieldExpFieldPatPatQ FieldPatQ FieldExpQFunDepPredPredQ TyVarBndrQDecsQ RuleBndrQ TySynEqnQTExpunTypeInjectivityAnnKindQOverlap IncoherentOverlaps Overlappable Overlapping DerivClauseQDerivStrategyQ stockStrategyanyclassStrategynewtypeStrategy viaStrategyghc-boot-th-8.10.2GHC.LanguageExtensions.Type ExtensionStandaloneKindSignaturesCUSKsImportQualifiedPost StarIsTypeQuantifiedConstraintsNumericUnderscoresEmptyDataDerivingMonadFailDesugaring StrictDataStrictTypeApplicationsStaticPointersNamedWildCardsPartialTypeSignaturesPatternSynonyms EmptyCaseOverloadedLabelsDuplicateRecordFieldsHexFloatLiteralsNegativeLiteralsBinaryLiterals MultiWayIf LambdaCaseTraditionalRecordSyntax RelaxedLayoutNondecreasingIndentationDatatypeContexts!AlternativeLayoutRuleTransitionalAlternativeLayoutRuleExplicitForAllPackageImportsExplicitNamespaces TypeOperatorsImpredicativeTypes RankNTypesLiberalTypeSynonyms PatternGuards TupleSectionsPostfixOperators RecursiveDoGeneralizedNewtypeDerivingMonadComprehensionsTransformListCompParallelListCompRoleAnnotationsKindSignaturesEmptyDataDecls MagicHashExistentialQuantification UnicodeSyntaxFunctionalDependenciesNullaryTypeClassesMultiParamTypeClassesConstrainedClassMethodsFlexibleInstancesFlexibleContextsTypeSynonymInstances DerivingViaDerivingStrategies DeriveLiftDeriveAnyClassDefaultSignatures DeriveGenericDeriveFoldableDeriveTraversable DeriveFunctorAutoDeriveTypeableDeriveDataTypeableStandaloneDeriving ApplicativeDo InstanceSigs DataKinds PolyKindsConstraintKindsRebindableSyntaxBlockArgumentsDoAndIfThenElseNPlusKPatterns GADTSyntaxGADTs ViewPatterns RecordPunsRecordWildCardsDisambiguateRecordFields NumDecimalsOverloadedListsOverloadedStrings TypeInTypeTypeFamilyDependencies TypeFamilies BangPatternsUnliftedNewtypes UnboxedSums UnboxedTuplesAllowAmbiguousTypesScopedTypeVariablesImplicitPreludeImplicitParams QuasiQuotesTemplateHaskellQuotesTemplateHaskellArrowsParallelArrays JavaScriptFFIGHCForeignImportPrimCApiFFIInterruptibleFFIUnliftedFFITypesForeignFunctionInterfaceExtendedDefaultRulesRelaxedPolyRecMonoLocalBinds MonoPatBindsMonomorphismRestrictionUndecidableSuperClassesIncoherentInstancesUndecidableInstancesCppOverlappingInstancesLanguage.Haskell.TH.Lib unboxedTupEtupEmkBytesstandaloneDerivWithStrategyD derivClausetyVarSigkindSignoSig constraintKstarKkindedTVplainTVsigTforallTforallCtySynEqnclosedTypeFamilyDopenTypeFamilyD dataFamilyD newtypeInstD dataInstD pragRuleDclassDnewtypeDdataDtySynD thisModuleappsE varStrictType strictTypeunpacked notStrictisStrictequalPclassPparensTuInfixTstandaloneDerivD pragLineD instanceDstringE arithSeqElam1EuInfixEparensEdynpatGnormalG fromThenToRfromToR fromThenRfromRparensPuInfixP bytesPrimLInfoQTExpQTyLitQCxtQBodyQGuardQRangeQSourceStrictnessQSourceUnpackednessQBangQ StrictTypeQVarStrictTypeQ PatSynDirQ PatSynArgsQFamilyResultSigQLanguage.Haskell.TH.Ppr pprParendTypepprPatpprLitpprExppprintPprpprppr_list defaultFixity maxPrecedenceunboxedSumTypeNameunboxedSumDataNameunboxedTupleTypeNameunboxedTupleDataName tupleTypeName tupleDataName nameSpace namePackage nameModulenameBase extsEnabled isExtEnabledrunIOlocation isInstancereifyConStrictness reifyModulereifyAnnotations reifyRolesreifyInstances reifyType reifyFixityreifylookupValueNamelookupTypeNamerecover reportWarning reportErrorreportrunQ NameSpaceLocloc_end loc_start loc_module loc_filename loc_packageInfoTyVarIVarIPatSynIDataConI PrimTyConIFamilyITyConIClassIClassOpI ModuleInfo ParentNameSumAltSumArityArityUnlifted InstanceDecFixityFixityDirectionInfixNInfixLInfixRLit CharPrimL BytesPrimL StringPrimL DoublePrimL FloatPrimL WordPrimLIntPrimL RationalLIntegerLCharLStringLBodyGuardedBNormalBGuardNormalGPatGStmtRecSParSNoBindSBindSLetSRange FromThenToRFromToRFromR FromThenR DerivClause DerivStrategy ViaStrategyNewtypeStrategy StockStrategyAnyclassStrategy PatSynTypeTypeFamilyHeadTySynEqnForeignImportFExportFCallconv JavaScriptPrimCApiCCallStdCallSafety InterruptibleUnsafeSafePragma CompletePLinePAnnPRulePSpecialiseInstPInlineP SpecialisePInline InlinableNoInline RuleMatchConLikeFunLikePhases BeforePhase AllPhases FromPhaseRuleBndrRuleVar TypedRuleVar AnnTargetValueAnnotationModuleAnnotationTypeAnnotationCxtSourceUnpackednessNoSourceUnpackedness SourceUnpackSourceNoUnpackSourceStrictnessNoSourceStrictness SourceLazy SourceStrictDecidedStrictness DecidedUnpack DecidedLazy DecidedStrictConRecGadtCGadtCForallCInfixCNormalCRecCBang PatSynDir ExplBidirUnidir ImplBidir PatSynArgs RecordPatSyn PrefixPatSyn InfixPatSyn TyVarBndrPlainTVKindedTVFamilyResultSigTyVarSigNoSigKindSigTyLitNumTyLitStrTyLitRoleInferRPhantomRNominalRRepresentationalR AnnLookupAnnLookupModule AnnLookupNameKind Data.TypeableTypeRepBoolIntOrderingTyConmkFunTyData.Typeable.InternalTypeabletypeOf7typeOf6typeOf5typeOf4typeOf3typeOf2typeOf1 rnfTypeReptypeRepFingerprint typeRepTyCon typeRepArgs splitTyConApp funResultTygcast2gcast1gcasteqTcast showsTypeReptypeReptypeOfrnfTyContyConFingerprint tyConName tyConModule tyConPackage Data.ProxyProxyData.Type.Equality:~:Refl:~~:HReflShow Data.DynamicDynamicGHC.Err undefinedshowEq==/=Ord<=<False-:>Truenot&&||GHC.Num+*-GHC.Realdivmodquotremnegateabssignumoddeven%integer-wired-inGHC.Integer.TypeIntegerGHC.EnumenumFrom enumFromTo enumFromThenenumFromThenTo