h*sy      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                                                       1.0.18(c) 2019-2024 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-Inferredd 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] = FalseexpressDetermines whether no element of the given list satisfies the predicate. > none even [3,5,7,11,13] True > none even [7,5,3,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]expressLike $ but allows providing a function to  values.express.Merges two lists discarding repeated elements.'The argument lists need to be in order.5(c) 2016-2024 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-Inferred7 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 operatorsexpress&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-2024 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-InferredW  (c) 2019-2024 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'", ...]0express name (undefined :: Float) = "x" names (undefined :: Float) = ["x", "y", "z", "x'", ...]1express name (undefined :: Complex) = "x" names (undefined :: Complex) = ["x", "y", "z", "x'", ...]2express name (undefined :: Rational) = "q" names (undefined :: Rational) = ["q", "r", "s", "q'", ...]3express name (undefined :: Ordering) = "o" names (undefined :: Ordering) = ["o", "p", "q", "o'", ...]4express name (undefined :: Char) = "c" names (undefined :: Char) = ["c", "d", "e", "c'", "d'", ...]5express name (undefined :: Integer) = "x" names (undefined :: Integer) = ["x", "y", "z", "x'", ...]6express name (undefined :: Int) = "x" names (undefined :: Int) = ["x", "y", "z", "x'", "y'", ...]7express name (undefined :: Bool) = "p" names (undefined :: Bool) = ["p", "q", "r", "p'", "q'", ...]8express name (undefined :: ()) = "u" names (undefined :: ()) = ["u", "v", "w", "u'", "v'", ...](c) 2019-2024 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-Inferred5 ;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])AexpressNormalizes a type by applying it to units to make it star-kinded. (cf. @) normalizeTypeUnits ''Int === [t| Int |] normalizeTypeUnits ''Maybe === [t| Maybe () |] normalizeTypeUnits ''Either === [t| Either () () |]BexpressGiven 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) FalseCexpressThe negation of B.DexpressGiven 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 and newtype declarations and it is useful when generating typeclass instances.Eexpress 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])]Fexpress Is the given  a type synonym? :> putStrLn $(stringE . show =<< isTypeSynonym 'show) False ;> putStrLn $(stringE . show =<< isTypeSynonym ''Char) False <> putStrLn $(stringE . show =<< isTypeSynonym ''String) TrueGexpressResolves a type synonym. > putStrLn $(stringE . show =<< typeSynonymType ''String) AppT ListT (ConT ''Char)NexpressLookups the name of a value throwing an error when it is not found. 8> putStrLn $(stringE . show =<< lookupValN "show") 'showOexpressLists all unbound variables in a type. This intentionally excludes the  constructor.Pexpress$Binds all unbound variables using a  constructor. (cf. O)Qexpress"Same as toBounded but lifted over <9:=>?@ABCDEFGJKN;MHILOPQ <9:=>?@ABCDEFGJKN;MHILOPQ(c) 2019-2024 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-Inferred=Rexpress Derives a  instance for the given type .This function needs the TemplateHaskell extension.SexpressSame as R4 but does not warn when instance already exists (R is preferable).Texpress Derives a  instance for a given type 3 cascading derivation of type arguments as well.RTSRTS(c) 2016-2024 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-InferredPUexpress 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 :: ()) GT expressShows a   consistently across different GHC versions. This is needed in the implementation of U.On GHC <= 9.4: > show listTyCon "[]"On GHC >= 9.6: > show listTyCon "List" On all GHCs: > showTyCon listTyCon "[]"On GHC <= 9.6: > show unitTyCon "()"On GHC >= 9.8: > show unitTyCon "Unit" On all GHCs: > showTyCon unitTyCon "()"Further exceptions to `show :: TyCon -> String` may be added here on future versions.Vexpress*Returns the functional arity of the given  . '> tyArity $ typeOf (undefined :: Int) 0 .> tyArity $ typeOf (undefined :: Int -> Int) 1 -> tyArity $ typeOf (undefined :: (Int,Int)) 0Wexpress.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)) BoolXexpressDeconstructs 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. Y and Z)YexpressReturns the argument   of a given functional  . 2argumentTy $ typeOf (undefined :: Int -> Char) Int6This function raises an error on non-functional types.(cf. Z)ZexpressReturns 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. Y and W)[expressThis 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: Data.Express.Utils.Typeable.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  expressThe list type constructor as a  expressThe unit type constructor as a  `expressReturns whether a   is functional. > isFunTy $ typeOf (undefined :: Int -> Int) True > isFunTy $ typeOf (undefined :: Int) Falseaexpress.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])) 0bexpressConstructs a comparison type ( a -> a -> Bool ") from the given argument type. ?> mkComparisonTy $ typeOf (undefined :: Int) Int -> Int -> Bool <> mkComparisonTy $ typeOf (undefined :: ()) () -> () -> BoolcexpressConstructs a "compare" type ( a -> a -> Ordering ") from the given argument type. > mkCompareTy $ typeOf (undefined :: Int) Int -> Int -> Ordering => mkCompareTy $ typeOf (undefined :: ()) () -> () -> OrderingdexpressO(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 ]eexpress2Returns 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)]fexpressAn infix alias for  . It is right associative.8VX`YZW\]^bc_U[deaf VX`YZW\]^bc_U[deaff9 (c) 2019-2024 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-Inferred0gexpressValues of type g represent objects or applications between objects. Each object is encapsulated together with its type and string representation. Values encoded in gs are always monomorphic.An g can be constructed using:k, for values that are   instances;j, for values that are not   instances, like functions;i, for applications between gs. > val False False :: Bool 0> value "not" not :$ val False not False :: BoolAn g can be evaluated using t, u or v. > evl $ val (1 :: Int) :: Int 1 1> evaluate $ val (1 :: Int) :: Maybe Bool Nothing > eval 'a' (val 'b') 'b' ing a value of type g will return a pretty-printed representation of the expression together with its type. 9> show (value "not" not :$ val False) "not False :: Bool"g is like  2 but has support for applications and variables (i, m).The m underscore convention: Functions that manipulate g)s usually follow the convention where a j whose  representation starts with '_' represents a miable.hexpressa j enconded as  and  iexpress(function application between expressionsjexpressO(1). It takes a string representation of a value and a value, returning an g- with that terminal value. For instances of  , it is preferable to use k. '> 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]kexpressO(1). A shorthand for j for values that are   instances. > val (0 :: Int) 0 :: Int > val 'a' 'a' :: Char > val True True :: BoolExample equivalences to j: val 0 = value "0" 0 val 'a' = value "'a'" 'a' val True = value "True" TruelexpressO(n). Creates an g' representing a function application.  an g! application if the types match,  otherwise. (cf. i) :> 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 () NothingmexpressO(1). Creates an g 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 j6 whose string representation starts with underscore ('_').nexpressO(n). Computes the type of an expression. This raises errors, but this should not happen if expressions are smart-constructed with l. > 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'oexpressO(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)pexpressO(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) NothingqexpressO(n). Returns whether the given g is ill typed. (cf. r) > 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') TruerexpressO(n). Returns whether the given g is well typed. (cf. q) +> isWellTyped (absE :$ val (1 :: Int)) True %> isWellTyped (absE :$ val 'b') FalsesexpressO(n). Returns whether the given g? is of a functional type. This is the same as checking if the  of the given g is non-zero. .> isFun (value "abs" (abs :: Int -> Int)) True > isFun (val (1::Int)) False > isFun (value "const" (const :: Bool -> Bool -> Bool) :$ val False) TruetexpressO(n). ; the value of an expression when possible (correct type), - otherwise. This does not catch errors from     js. > 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 NothinguexpressO(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 0vexpressO(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 u or t.wexpressO(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' NothingxexpressO(n). Like y; 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)"yexpressO(n). Like z2 but allows specifying the surrounding precedence. &> showPrecExpr 6 (one -+- two) "1 + 2" (> showPrecExpr 7 (one -+- two) "(1 + 2)"zexpressO(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){expressO(n)". Compares the complexity of two gs. 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 gs 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. U)!This comparison is a total order.}expressO(n). A fast total order between g!s that can be used when sorting g values.&This is lazier than its counterparts { and |" and tries to evaluate the given gs as least as possible.~expressO(n)!. Unfold a function application g( 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 i 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 g into a list of values. > let pair' a b = value "," ((,) :: Bool->Char->(Bool,Char)) :$ a :$ b 6> pair' (val True) (val 'a') (True,'a') :: (Bool,Char) > unfoldTuple $ pair' (val True) (val 'a') [True :: Bool,'a' :: Char] > let trio' a b c = value ",," ((,,) :: Bool->Char->Int->(Bool,Char,Int)) :$ a :$ b :$ c > trio' (val False) (val 'b') (val (9 :: Int)) (False,'b',9) :: (Bool,Char,Int) > unfoldTuple $ trio' (val False) (val 'b') (val (9 :: Int)) [False :: Bool,'b' :: Char,9 :: Int]NOTE: this function returns an empty list when the representation of the tupling function is (,), (,,), (,,,) or (,,,...)+. This is intentional, allowing the   g instance to present (,) 1 2 differently than (1,2). expressO(n). Unfold a list g( into a list of values and a terminator.This works for lists "terminated" by an arbitrary expression. One can later check the second value of the return tuple to see if it is a proper list or string by comparing the string representation with [] or "".&This is used in the implementation of  . expressO(1)+. Checks if a given expression is a tuple.expressO(n). Check if an g3 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 g 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 g 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 g is a terminal variable (m ). (cf. ). )> isVar $ var "x" (undefined :: Int) True > isVar $ val False False >> isVar $ value "not" not :$ var "p" (undefined :: Bool) FalseexpressO(1). Returns whether an g is a terminal value (h). +> 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 h constructor. Properties:  isValue (Value e) = True  isValue (e1 :$ e2) = False  isValue = not . isApp # isValue e = isVar e || isConst eexpressO(1). Returns whether an g is an application (i). *> 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 i 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 ({.) 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 gs with their types. 9> show (value "not" not :$ val False) "not False :: Bool"*ghijklmtuvnopwqrs{|}~zxy*ghijklmtuvnopwqrs{|}~zxy(c) 2019-2024 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-Inferred'express!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 gs, 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) = FalseThis function works on ill-typed expressions so long as the leaf/atom types match: > foldPair (xx -+- zero, xx) `isInstanceOf` foldPair (yy -+- zero, yy) Trueexpress Given two gs, 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 g( is an instance of the second argument g.expressO(n^2). Checks if an g 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-2024 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-Inferred express A trie of gs.In the representation,  matches an App and  g an expression.express An empty .express Constructs a  encoding a single expression.express Merges two s.express Inserts an g into a .express List all g stored in a $ along with their associated values.express Constructs a  form a list of key gs and associated values.express*Maps a function to the stored values in a .expressPerforms a lookup in a .   (c) 2019-2024 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-InferredMexpressO(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 g. 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-2024 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-InferredҊ expressO(1) . Creates a m&iable with the same type as the given g. 9> let one = val (1::Int) > "x" `varAsTypeOf` one x :: Int '> "p" `varAsTypeOf` val False p :: BoolexpressO(1). Creates an g7 representing a typed hole with the type of the given g. (cf. ) >> val (1::Int) 1 :: Int > holeAsTypeOf $ val (1::Int) _ :: IntexpressO(1). Creates an g6 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 g 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 g. (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-2024 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-InferredexpressO(n). Folds a list of g with function application (i ). 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 i 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 g values into a single g. (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 g 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 g3 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 g values into a single g. (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 g 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 g: 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 gs into a single g. (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 g 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 g$ representing a list into a list of g 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-2024 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 gs. expr False = val False expr (Just True) = value "Just" (Just :: Bool -> Maybe Bool) :$ val True The function % can be contrasted with the function k:k! always encodes values as atomic h gs -- shallow encoding.. ideally encodes expressions as applications (i ) between h gs -- 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-2024 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-Inferredexpress 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-2024 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-Inferred'express*Lists valid applications between lists of gs > [notE, plus] >$$< [false, true, zero] [not False :: Bool,not True :: Bool,(0 +) :: Int -> Int]express+Lists valid applications between a list of g s and an g. > [plus, times] >$$ zero [(0 +) :: Int -> Int,(0 *) :: Int -> Int]express$Lists valid applications between an g and a list of gs. > notE >$$< [false, true, zero] [not False :: Bool,not True :: Bool]ghitjlkmuvnopwqrs{|}zyx~(c) 2019-2024 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-InferredcexpressO(1). Reifies an   instance into a list of gs. 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 gs. 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 g.expressO(1). Reifies a  instance into a list of gs. 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 g. :> 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 g 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 g. ;> 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 g 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 g.)Given that the instances list has length m and that the given g 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 g.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 g.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 g.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 g.expressO(n+m). Like ) but lifted over an instance list and an g. 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 g.expressO(n+m). Like , but returns a list of variables encoded as gs.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-2024 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-Inferred#expressLike  but allows customization of the list of variable names. (cf. , ) > canonicalizeWith (const ["i","j","k","l",...]) (xx -+- yy) i + j :: Int The argument g 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 g 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 g3 that makes variable names appear in order using  as provided by  . By using  it can  gs. > 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 g is canonical: if applying  is an identity using  as provided by .express'Returns all canonical variations of an g 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 g" 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 g" 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 g% 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 gs 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. express(Variable names existing in a given Expr.This function is not exported. expressVariables that are not holes.This function is not exported. expressCanonicalizes an g- while keeping the given variables untouched. >> canonicalizeKeeping [zz] (zz -+- ii -+- jj) z + x + y :: Int > canonicalizeKeeping [ii,jj] (zz -+- ii -+- jj) x + i + j :: IntThis function is not exported.  (c) 2019-2024 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-Inferred$ghijklmtuvnopwqrs{|}zyx~RTSghijklmtuvnopwqrs{|}zyx~RTS(c) 2019-2024 Rudy Matela$3-Clause BSD (see the file LICENSE) Rudy Matela  Safe-Inferredexpressg representing a hole of   type. > b_ _ :: Boolexpressg representing a variable p ::  . > pp p :: Boolexpressg representing a variable q ::  . > qq q :: Boolexpressg representing a variable r ::  . > rr r :: Boolexpressg representing a variable p' ::  . > pp' p' :: Boolexpress  encoded as an g. > false False :: Boolexpress  encoded as an g. > true True :: Boolexpress The function   encoded as an g. > notE not :: Bool -> Boolexpress The function  encoded as an g. #> andE (&&) :: Bool -> Bool -> Boolexpress The function  encoded as an g. "> orE (||) :: Bool -> Bool -> Boolexpress The function ==> lifted over gs. )> false -==>- true False ==> True :: Bool %> evl $ false -==>- true :: Bool TrueexpressThe ==> operator encoded as an gexpress The function   lifted over the g type. > not' false not False :: Bool > evalBool $ not' false True > not' pp not p :: Boolexpress The function   lifted over the g type. > pp -&&- qq p && q :: Bool '> false -&&- true False && True :: Bool "> evalBool $ false -&&- true Falseexpress The function   lifted over the g 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 g. > zero 0 :: Intexpress The value 1 bound to the   type encoded as an g. > one 1 :: Intexpress The value 2 bound to the   type encoded as an g. > two 2 :: Intexpress The value 3 bound to the   type encoded as an g. > three 3 :: Intexpress The value 4 bound to the   type encoded as an g. > four 4 :: Intexpress The value 5 bound to the   type encoded as an g. > five 5 :: Intexpress The value 6 bound to the   type encoded as an g. > six 6 :: Intexpress The value 7 bound to the   type encoded as an g. > seven 7 :: Intexpress The value 8 bound to the   type encoded as an g. > eight 8 :: Intexpress The value 9 bound to the   type encoded as an g. > nine 9 :: Intexpress The value 10 bound to the   type encoded as an g. > ten 10 :: Intexpress The value 11 bound to the   type encoded as an g. > eleven 11 :: Intexpress The value 12 bound to the   type encoded as an g. > twelve 12 :: Intexpress The value -1 bound to the   type encoded as an g. > minusOne -1 :: Intexpress The value -2 bound to the   type encoded as an g. > minusOne -2 :: IntexpressA variable function f" of 'a -> a' type lifted over the g type. This works for  ,  ,  and their lists > ff xx f x :: Int > ff one f 1 :: Intexpress A variable f$ of 'Int -> Int' type encoded as an g. > ffE f :: Int -> IntexpressA variable function g" of 'a -> a' type lifted over the g type. This works for  ,  ,  and their lists. > gg yy g y :: Int > gg minusTwo gg (-2) :: Intexpress A variable g$ of 'Int -> Int' type encoded as an g. > ggE g :: Int -> IntexpressA variable function h& of 'Int -> Int' type lifted over the g type. > hh zz h z :: Intexpress A variable h$ of 'Int -> Int' type encoded as an g. > hhE h :: Int -> IntexpressA variable function f' of 'a -> a -> a' type lifted over the g type. This works for  ,  ,  and their lists > ff2 xx yy f x y :: Int > ff2 one two f 1 2 :: Int:The result type is bound to the type of the last argument.expressA variable function f, of 'a -> a -> a -> a' type lifted over the g type. This works for  ,  ,  and their lists > ff3 xx yy zz f x y z :: Int "> ff3 one two three f 1 2 3 :: Int:The result type is bound to the type of the last argument.expressA variable function f1 of 'a -> a -> a -> a -> a' type lifted over the g type. This works for  ,  ,  and their lists %> ff3 xx yy zz xx' f x y z xx' :: Int )> ff3 one two three four f 1 2 3 4 :: Int:The result type is bound to the type of the last argument.expressA variable binary operator ? lifted over the g type. Works for  ,  , , [Int] and . > xx -?- yy x ? y :: Int > pp -?- qq p ? q :: Bool > xx -?- qq *** Exception: (-?-): unhandled type: 1 :: Int, False :: Bool accepted types are: (?) :: Int -> Int -> Int (?) :: Bool -> Bool -> Bool (?) :: Char -> Char -> Char (?) :: [Int] -> [Int] -> [Int] (?) :: [Char] -> [Char] -> [Char] (?) :: Int -> [Int] -> [Int] (?) :: Char -> [Char] -> [Char]expressA variable binary operator ? encoded as an g (cf. ) #> question :$ xx :$ yy x ? y :: Int $> question :$ pp :$ qq p ? q :: BoolexpressA variable binary operator o lifted over the g type. Works for  ,  , , [Int] and . > xx `oo` yy x `o` y :: Int > pp `oo` qq p `o` q :: Bool > xx `oo` qq *** Exception: oo: unhandled type: 1 :: Int, False :: Bool accepted types are: o :: Int -> Int -> Int o :: Bool -> Bool -> Bool o :: Char -> Char -> Char o :: [Int] -> [Int] -> [Int] o :: [Char] -> [Char] -> [Char]expressA variable binary function o encoded as an g (cf. )  > ooE :$ xx :$ yy x `o` y :: Int !> ooE :$ pp :$ qq p `o` q :: Boolexpress The operator   for the   type for use on gs. (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 g 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 g. "> minus :$ one (1 -) :: Int -> Int #> minus :$ one :$ zero 1 - 0 :: Intexpress The function   for the   type lifted over the g type. (See also  .) "> six `div'` four 6 `div` 4 :: IntexpressInteger division   encoded as an g. %> divE :$ two (2 `div`) :: Int -> Int '> divE :$ two :$ three 2 `div` 3 :: Intexpress The function   for the   type lifted over the g type. (See also  .) "> six `mod'` four 6 `mod` 4 :: IntexpressInteger modulo   encoded as an g. %> modE :$ two (2 `mod`) :: Int -> Int '> modE :$ two :$ three 2 `mod` 3 :: Intexpress The function   for the   type lifted over the g type. (See also  .) $> six `quot'` four 6 `quot` 4 :: IntexpressInteger quotient   encoded as an g. '> quotE :$ two (2 `quot`) :: Int -> Int )> quotE :$ two :$ three 2 `quot` 3 :: Intexpress The function   for the   type lifted over the g type. (See also  .) "> six `rem'` four 6 `rem` 4 :: IntexpressInteger remainder   encoded as an g. %> remE :$ two (2 `rem`) :: Int -> Int '> remE :$ two :$ three 2 `rem` 3 :: IntexpressConstructs an application of  as an g. 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 g . (See also .) > idE :$ xx id x :: Int > idE :$ zero id 0 :: Int ,> evaluate $ idE :$ zero :: Maybe Int Just 0express The function  encoded as an g. (cf. )express The function  encoded as an g. (cf. )express The function  encoded as an g. (cf. )express The function  encoded as an g. (cf. )express The function  encoded as an g. (cf. )express The function  encoded as an g. (cf. )expressThe  function lifted over the g type. "> const' zero one const 0 1 :: Int"This works for the argument types  , ,   and their lists.express  over the   type lifted over the g type. > negate' xx negate x :: Int > evl (negate' one) :: Int -1express  over the   type encoded as an g > negateE negate :: Int -> Intexpress  over the   type lifted over the g type. > abs' xx' abs x' :: Int > evl (abs' minusTwo) :: Int 2express  over the   type encoded as an g. > absE abs :: Int -> Intexpress  over the   type lifted over the g type. > signum' xx' signum x' :: Int "> evl (signum' minusTwo) :: Int -1express  over the   type encoded as an g. > signumE signum :: Int -> Intexpress  with an   argument lifted over the g type. '> odd' (xx -+- one) odd (x + 1) :: Bool > evl (odd' two) :: Bool Falseexpress  with an   argument lifted over the g type. )> even' (xx -+- two) even (x + 2) :: Bool > evl (even' two) :: Bool Trueexpress A hole of  type encoded as an g. > c_ _ :: Charexpress A hole of  type encoded as an g. > cs_ _ :: [Char]expressA variable named c of type  encoded as an g. > cc c :: CharexpressA variable named c of type  encoded as an g. > dd d :: CharexpressA variable named cs of type  encoded as an g. > ccs cs :: [Char]expressThe character 'a' encoded as an g. > ae 'a' :: Char > evl ae :: Char 'a'expressThe character 'b' encoded as an g > bee 'b' :: Char > evl bee :: Char 'b'expressThe character 'c' encoded as an g > cee 'c' :: Char > evl cee :: Char 'c'expressThe character 'd' encoded as an g > dee 'd' :: Char > evl dee :: Char 'd'expressThe character 'z' encoded as an g > zed 'z' :: Char > evl zed :: Char 'z'(cf. )expressThe character 'z' encoded as an g > zee 'z' :: Char > evl zee :: Char 'z'(cf. )express"The space character encoded as an g > space ' ' :: Charexpress'The line break character encoded as an g > lineBreak '\n' :: CharexpressThe  function lifted over g > ord' bee ord 'b' :: Int > evl (ord' bee) 98expressThe  function encoded as an gexpressA typed hole of [Int] type encoded as an g. > is_ _ :: [Int]expressA variable named xs of type [Int] encoded as an g. > xxs xs :: [Int]expressA variable named ys of type [Int] encoded as an g. > yys ys :: [Int]expressA variable named zs of type [Int] encoded as an g. > yys ys :: [Int]expressAn empty list of type [Int] encoded as an g. > nil [] :: [Int]express An empty  encoded as an g. > emptyString "" :: Stringexpress"The empty list '[]' encoded as an g.express"The empty list '[]' encoded as an g.express"The empty list '[]' encoded as an g.expressThe list constructor with   as element type encoded as an g. #> cons (:) :: Int -> [Int] -> [Int] !> cons :$ one :$ nil [1] :: [Int]Consider using  and  when building lists of g.expressThe list constructor  :  encoded as an g.expressThe list constructor  :  encoded as an g.expressThe list constructor  :  encoded as an g.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 g& 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 g.express#List concatenation lifted over the g& 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 g& 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 g& 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 g& 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 g& 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 g& 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 g& 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 g& 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 g& 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 TrueexpressList  lifted over the g& type. Works for the element types  ,  and  . &> drop' zero nilInt drop 0 [] :: [Int] ?> drop' one (false -:- unit true) drop 1 [False,True] :: [Bool]expressList  lifted over the g& type. Works for the element types  ,  and  . &> take' zero nilInt take 0 [] :: [Int] ?> take' one (false -:- unit true) take 1 [False,True] :: [Bool]express lifted over gs > absE -$- one abs $ 1 :: Int Works for  ,  ,  argument types and their lists.express#Constructs an equation between two gs. > xx -==- zero x == 0 :: Bool > cc -==- dee c == 'd' :: BoolThis works for the  ,  ,  argument types and their lists.express%Constructs an inequation between two gs. > xx -/=- zero x /= 0 :: Bool > cc -/=- ae c /= 'a' :: Boolexpress7Constructs a less-than-or-equal inequation between two gs. > xx -<=- zero x <= 0 :: Bool > cc -<=- ae c <= 'a' :: Boolexpress.Constructs a less-than inequation between two gs. > xx -<- zero x < 0 :: Bool > cc -<- bee c < 'b' :: Boolexpress A function if :: Bool -> a -> a -> a lifted over the g type that encodes if-then-else functionality. This is properly 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'express A function case :: Bool -> a -> a -> a lifted over the g type that encodes case-of-False-True functionality. This is properly displayed as a case-of-False-True expression. >> caseBool pp zero xx (case p of False -> 0; True -> x) :: Int > zz -*- caseBool pp xx yy z * (case p of False -> x; True -> y) :: Int > caseBool pp false true -||- caseBool qq true false (caseBool p of False -> False; True -> True) || (caseBool q of False -> True; True -> False) :: Bool 5> evl $ caseBool true (val 'f') (val 't') :: Char 't'By convention, the   case comes before   as  False < True and data Bool = False | True.When evaluating, this is equivalent to if with arguments reversed. Instead of using this, you are perhaps better of using if encoded as an expression. This is just here to be consistent with .express A function $case :: Ordering -> a -> a -> a -> a lifted over the g type that encodes case-of-LT-EQ-GT functionality. This is properly displayed as a case-of-LT-EQ-GT expression. (cf. ) > caseOrdering (xx `compare'` yy) zero one two (case compare x y of LT -> 0; EQ -> 1; GT -> 2) :: Int > evl $ caseOrdering (val EQ) (val 'l') (val 'e') (val 'g') :: Char 'e'!By convention cases are given in  ,   and   order as  LT < EQ < GT and data Ordering = LT | EQ | GT.expressConstructs an g -encoded  operation between two gs. ,> xx `compare'` zero compare x 0 :: Ordering -> compare' ae bee compare 'a' 'b' :: Orderingexpress bound to the    type encoded as an g.This is an alias to .express bound to the    type encoded as an g.express bound to the    type encoded as an g.expressThe   constructor of the   element type encoded as an g.expressThe   constructor of the   element type encoded as an g.expressThe   constructor lifted over the g type.This works for the  ,  , ! argument types and their lists. > just zero Just 0 :: Maybe Int > just false Just False :: Maybe BoolexpressAn infix synonym of . > zero -|- xxs(0,xs) :: (Int,[Int]) 7> ae -|- (bee -:- unit cee) ('a',"bc") :: (Char,[Char])express!The pair constructor lifted over gs."This works for some variations of  ,   and  element types and their lists. > pair zero xxs(0,xs) :: (Int,[Int])Differently from , when this works,- it always constructs a well-typed expression.expressThe pair constructor ( :: ... -> (Int,Int) ) encoded as an g.express(The triple/trio constructor lifted over gs.)This works for some combinations of the  ,   and  element types and their lists.express&The quadruple constructor lifted over gs.)This works for some combinations of the  ,   and  element types and their lists.express&The quintuple constructor lifted over gs.This only works for the   element type.express%The sixtuple constructor lifted over gs.This only works for the   element type.expressA typed hole of [Bool] type encoded as an g. > bs_ _ :: [Bool]expressg representing a variable p' :: `[Bool]`. > pps ps :: [Bool]expressA typed hole of '[Bool]' type > qqs qs :: [Bool]express lifted over the g type. > and' pps and ps :: Bool .> evl (and' $ expr [False,True]) :: Bool Falseexpress lifted over the g type. > or' pps or ps :: Bool ,> evl (or' $ expr [False,True]) :: Bool Trueexpress of   elements lifted over the g type. > sum' xxs sum xs :: Int )> evl (sum' $ expr [1,2,3::Int]) :: Int 6express of   elements lifted over the g type.  > product' xxs product xs :: Int -> evl (product' $ expr [1,2,3::Int]) :: Int 6expressThe   constructor lifted over gs. > val (2 :: Integer) -%- val (3 :: Integer) 2 % 3 :: Ratio IntegerThis only accepts gs bound to the   type.express#Function composition encoded as an g: ;> compose (.) :: (Int -> Int) -> (Int -> Int) -> Int -> IntexpressFunction composition  lifted over g. -> 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 g ,> mapE map :: (Int -> Int) -> [Int] -> [Int]express lifted over gs. +> map' absE (unit one) map abs [1] :: [Int]express lifted over gs. 9> foldr' plus zero (unit one) foldr (+) zero [1] :: [Int]express lifted over gs. 1> filter' absE (unit one) filter odd [1] :: [Int]express  lifted over gs. $> enumFrom' zero enumFrom 0 :: [Int] Works for  s,  s and s.express  lifted over g s named as ".." for pretty-printing. > one -.. () [1..] :: [Int] Works for  s,  s and s.express  lifted over gs /> enumFromTo' zero four enumFromTo 0 4 :: [Int]express  lifted over gs but named as ".." for pretty-printing.  > zero -..- four [0..4] :: [Int]express  lifted over gs 3> enumFromThen' zero ten enumFromThen 0 10 :: [Int]express  lifted over gs but named as ",.." for pretty printing. &> (zero,ten) --.. () [0,10..] :: [Int]express  lifted over gs. => enumFromThenTo' zero two ten enumFromThenTo 0 2 10 :: [Int]express  lifted over gs but named as ",.." for pretty-printing. )> (zero,two) --..- ten [0,2..10] :: [Int]ghitjlkmuvnopwqrs{|}zyx~RTS 032675564444  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\                                                                                       -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                %express-1.0.18-LcWm5D1mpNvFgCeYITuRFAData.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.BasicData.Express.InstancesData.Express.CanonData.Express.FixturesexpressData.Express.Utils canonicalize mapValuescanonicalVariations deriveExpress Data.ExpressnubSort nubSortBy isSubsetOfisPermutationOfisNubnonelookupId+++unquoteatomicouternmostPrecisNegativeLiteralisInfixprecisPrefixisInfixedPrefixtoPrefix primeCyclevariableNamesFromTemplateNamenamenames$fName(,,,,,,,,,,,)$fName(,,,,,,,,,,)$fName(,,,,,,,,,)$fName(,,,,,,,,)$fName(,,,,,,,)$fName(,,,,,,) $fName(,,,,,) $fName(,,,,)$fNameGeneralCategory $fNameWord64 $fNameWord32 $fNameWord16 $fNameWord8 $fNameInt64 $fNameInt32 $fNameInt16 $fNameInt8 $fNameWord $fNameList $fName(,,,) $fName(,,) $fName(,) $fNameEither $fNameMaybe $fNameFUN $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 $fExpressList$fExpress(,,,) $fExpress(,,) $fExpress(,)$fExpressEither$fExpressMaybe$fExpressOrdering $fExpressChar$fExpressInteger $fExpressInt $fExpressBool $fExpress()deriveExpressIfNeededderiveExpressCascading>$$<>$$$$<reifyEqreifyOrd reifyEqOrd reifyNamemkEqmkOrdmkOrdLessEqualmkName mkNameWithlookupComparisonisEqTisOrdTisEqOrdTisEqisOrdisEqOrd mkComparison mkEquationmkComparisonLTmkComparisonLE lookupName lookupNames listVarsWith validApps findValidApppreludeNameInstancescanonicalizeWithcanonicalizationWithisCanonicalWithcanonicalization isCanonicalmostGeneralCanonicalVariationmostSpecificCanonicalVariationfastCanonicalVariationsfastMostGeneralVariationfastMostSpecificVariationb_ppqqrrpp'falsetruenotEandEorE-==>-impliesnot'-&&--||-i_xxyyzzxx'iijjkkii'llmmnnzeroonetwothreefourfivesixseveneightnineteneleventwelveminusOneminusTwoffffEggggEhhhhEff2ff3ff4-?-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'drop'take'-$--==--/=--<=--<-if'caseBool caseOrderingcompare'nothing nothingInt nothingBooljustIntjustBooljust-|-paircommatriple quadruple quintuplesixtuplebs_ppsqqsand'or'sum'product'-%-compose-.-mapEmap'foldr'filter' enumFrom'-.. enumFromTo'-..- enumFromThen'--..enumFromThenTo'--..-ghc-prim GHC.ClassescomparebaseGHC.List nubMergeBynubMergezipWith Data.OldListsortBy genericLength Data.Foldable maximumBy minimumBygenericReplicate genericTake genericDropgenericSplitAt genericIndexlengthfoldlfoldrnullfoldl'foldl1sumproductfoldr1maximumminimumelemheadgroupgroupByfilterunfoldr transposesortOncycleGHC.Base++concatzipunconstaillastinitfoldl1'scanlscanl1scanl'scanrscanr1iterateiterate'repeat replicate takeWhile dropWhiletakedropsplitAtspanbreakreverseandoranyallnotElem concatMap!!zip3zipWith3unzipunzip3find dropWhileEnd stripPrefix elemIndex elemIndices findIndex findIndices isPrefixOf isSuffixOf isInfixOfnubnubBydeletedeleteBy\\unionunionBy intersect intersectBy intersperse intercalate partitionData.Traversable mapAccumL mapAccumRinsertByzip4zip5zip6zip7zipWith4zipWith5zipWith6zipWith7unzip4unzip5unzip6unzip7deleteFirstsByinitstails subsequences permutationssort singletonlinesunlineswordsunwords Data.ListisSubsequenceOfString GHC.TypesChar GHC.UnicodeGeneralCategoryControlUppercaseLetterLowercaseLetterTitlecaseLetterModifierLetter OtherLetterNonSpacingMarkSpacingCombiningMark EnclosingMark DecimalNumber LetterNumber OtherNumberConnectorPunctuationDashPunctuationOpenPunctuationClosePunctuation InitialQuote FinalQuoteOtherPunctuation MathSymbolCurrencySymbolModifierSymbol OtherSymbolSpace LineSeparatorParagraphSeparatorFormat Surrogate PrivateUse NotAssigned Data.CharisLetterisAlphaordGHC.CharchrGHC.Show showLitChar intToDigitgeneralCategoryisAsciiisLatin1 isAsciiLower isAsciiUpper isControlisPrintisSpaceisUpper isUpperCaseisLower isLowerCase isAlphaNumisDigit isOctDigit isHexDigit isPunctuationisSymboltoUppertoLowertoTitleGHC.Read lexLitChar readLitChar digitToIntisMarkisNumber isSeparatorData.Semigroup.InternalAnygetAnySumgetSumProduct getProduct Data.MonoidLastgetLastFirstgetFirstMonoidmemptymappendmconcatAltgetAltAllgetAllEndoappEndoDualgetDualApgetAp<> GHC.MaybeMaybeNothingJust Data.MaybemaybeisJust isNothingfromJust fromMaybe maybeToList listToMaybe catMaybesmapMaybe Data.EitherEitherRightLefteitherleftsrightspartitionEithersisLeftisRightfromLeft fromRight$idconst.flip Data.Functionfixon& applyWhen MonadPlusmzeromplusMonad>>=return>>Functorfmap<$Control.Monad.Fail MonadFailfailmapMsequenceforM Control.MonadforeverliftMguardjoin=<<whenliftM2liftM3liftM4liftM5ap Data.FunctorvoidmapM_forM_ sequence_msumfilterM>=><=< mapAndUnzipMzipWithM zipWithM_foldMfoldM_ replicateM replicateM_unless<$!>mfiltertemplate-haskellLanguage.Haskell.TH.SyntaxForallTQForeignImportFExportFUnliftedType ForallVisTAppTAppKindTSigTVarTConT PromotedTInfixTUInfixTPromotedInfixTPromotedUInfixTParensTTupleT UnboxedTupleT UnboxedSumTArrowT MulArrowT EqualityTListTPromotedTupleT PromotedNilT PromotedConsTStarT ConstraintTLitT WildCardTImplicitParamTDecidedStrictness DecidedLazy DecidedStrict DecidedUnpackSourceStrictness SourceLazy SourceStrictNoSourceStrictnessSourceUnpackedness SourceUnpackSourceNoUnpackNoSourceUnpackednessFixityConNormalCRecCInfixCForallCGadtCRecGadtCghc-boot-th-9.6.3GHC.LanguageExtensions.Type ExtensionCppOverlappingInstancesUndecidableInstancesIncoherentInstancesUndecidableSuperClassesMonomorphismRestrictionMonoLocalBindsDeepSubsumptionRelaxedPolyRecExtendedDefaultRulesForeignFunctionInterfaceUnliftedFFITypesInterruptibleFFICApiFFIGHCForeignImportPrim JavaScriptFFIParallelArraysArrowsTemplateHaskellTemplateHaskellQuotes QualifiedDo QuasiQuotesImplicitParamsImplicitPreludeScopedTypeVariablesAllowAmbiguousTypes UnboxedTuples UnboxedSumsUnliftedNewtypesUnliftedDatatypes BangPatterns TypeFamiliesTypeFamilyDependencies TypeInTypeOverloadedStringsOverloadedLists NumDecimalsDisambiguateRecordFieldsRecordWildCardsNamedFieldPuns ViewPatternsGADTs GADTSyntaxNPlusKPatternsDoAndIfThenElseBlockArgumentsRebindableSyntaxConstraintKinds PolyKinds DataKindsTypeData InstanceSigs ApplicativeDo LinearTypesStandaloneDerivingDeriveDataTypeableAutoDeriveTypeable DeriveFunctorDeriveTraversableDeriveFoldable DeriveGenericDefaultSignaturesDeriveAnyClass DeriveLiftDerivingStrategies DerivingViaTypeSynonymInstancesFlexibleContextsFlexibleInstancesConstrainedClassMethodsMultiParamTypeClassesNullaryTypeClassesFunctionalDependencies UnicodeSyntaxExistentialQuantification MagicHashEmptyDataDeclsKindSignaturesRoleAnnotationsParallelListCompTransformListCompMonadComprehensionsGeneralizedNewtypeDeriving RecursiveDoPostfixOperators TupleSections PatternGuardsLiberalTypeSynonyms RankNTypesImpredicativeTypes TypeOperatorsExplicitNamespacesPackageImportsExplicitForAllAlternativeLayoutRule!AlternativeLayoutRuleTransitionalDatatypeContextsNondecreasingIndentation RelaxedLayoutTraditionalRecordSyntax LambdaCase MultiWayIfBinaryLiteralsNegativeLiteralsHexFloatLiteralsDuplicateRecordFieldsOverloadedLabels EmptyCasePatternSynonymsPartialTypeSignaturesNamedWildCardsStaticPointersTypeApplicationsStrict StrictDataEmptyDataDerivingNumericUnderscoresQuantifiedConstraints StarIsTypeImportQualifiedPostCUSKsStandaloneKindSignaturesLexicalNegationFieldSelectorsOverloadedRecordDotOverloadedRecordUpdateQuotenewNameExpVarEConELitEAppEAppTypeEInfixEUInfixEParensELamELamCaseE LamCasesETupE UnboxedTupE UnboxedSumECondEMultiIfELetECaseEDoEMDoECompE ArithSeqEListESigERecConERecUpdEStaticE UnboundVarELabelEImplicitParamVarE GetFieldE ProjectionEMatchClause Language.Haskell.TH.Lib.InternalExpQPatLitPVarPTupP UnboxedTupP UnboxedSumPConPInfixPUInfixPParensPTildePBangPAsPWildPRecPListPSigPViewPStmtBindSLetSNoBindSParSRecSTypeQDecFunDValDDataDNewtypeD TypeDataDTySynDClassD InstanceDSigDKiSigDForeignDInfixDDefaultDPragmaD DataFamilyD DataInstD NewtypeInstD TySynInstDOpenTypeFamilyDClosedTypeFamilyD RoleAnnotDStandaloneDerivD DefaultSigDPatSynD PatSynSigDImplicitParamBindDBangType VarBangTypeFieldExpFieldPatPatQFunDepPred TyVarBndrUnitDecsQRuleBndrRuleVar TypedRuleVarTySynEqnRoleNominalRRepresentationalRPhantomRInferRInjectivityAnnKindOverlap Overlappable OverlappingOverlaps Incoherent DerivClause DerivStrategy StockStrategyAnyclassStrategyNewtypeStrategy ViaStrategy TyVarBndrSpecCode examineCodeInlineNoInline InlinableDocLoc ModuleDocDeclDocArgDocInstDoc AnnLookupAnnLookupModule AnnLookupNameTyLitNumTyLitStrTyLit CharTyLitFamilyResultSigNoSigKindSigTyVarSig TyVarBndrPlainTVKindedTV Specificity SpecifiedSpec InferredSpec PatSynArgs PrefixPatSyn InfixPatSyn RecordPatSyn PatSynDirUnidir ImplBidir ExplBidirBangCxt AnnTargetModuleAnnotationTypeAnnotationValueAnnotationPhases AllPhases FromPhase BeforePhase RuleMatchConLikeFunLikePragmaInlinePOpaqueP SpecialisePSpecialiseInstPRulePAnnPLineP CompletePSafetyUnsafeSafe InterruptibleCallconvCCallStdCallCApiPrim JavaScriptTypeFamilyHead PatSynTypeRangeFromR FromThenRFromToR FromThenToRGuardNormalGPatGBodyGuardedBNormalBLitCharLStringLIntegerL RationalLIntPrimL WordPrimL FloatPrimL DoublePrimL StringPrimL BytesPrimL CharPrimLFixityDirectionInfixLInfixRInfixN InstanceDecAritySumAritySumAlt ParentName ModuleInfoInfoClassIClassOpITyConIFamilyI PrimTyConIDataConIPatSynIVarITyVarILoc loc_filename loc_package loc_module loc_startloc_end NameSpaceTExpunTypeLanguage.Haskell.TH.PprPprpprppr_listDerivStrategyQFamilyResultSigQ PatSynArgsQ PatSynDirQ TySynEqnQ RuleBndrQ FieldExpQVarStrictTypeQ StrictTypeQ VarBangTypeQ BangTypeQBangQSourceUnpackednessQSourceStrictnessQRangeQStmtQGuardQBodyQClauseQMatchQ DerivClauseQPredQCxtQTyLitQKindQConQDecQ FieldPatQInfoQCodeQTExpQ interruptiblerecover reportErrorrunIOdyn thisModule unTypeCodeunsafeCodeCoercecharLstringLintegerLintPrimL wordPrimL floatPrimL doublePrimL rationalL stringPrimL charPrimLlitPvarPtupP unboxedTupP unboxedSumPLanguage.Haskell.TH.LibconPinfixPtildePbangPasPwildPrecPlistPsigPviewPfieldPatclausevarEconElitEappEappTypeEinfixEinfixAppsectionLsectionRlamElamCaseE lamCasesEtupE unboxedTupE unboxedSumEcondEmultiIfEletEcaseEdoEcompEfromE fromThenEfromToE fromThenToElistEsigErecConErecUpdEstaticE unboundVarElabelEimplicitParamVarEmdoE getFieldE projectionEfieldExpguardedBnormalBnormalGEpatGEbindSletSnoBindSparSrecSfunDvalDdataDnewtypeDtySynDclassDinstanceWithOverlapDsigDforImpDpragInlD pragSpecD pragSpecInlD pragSpecInstD pragRuleDpragAnnD dataFamilyDopenTypeFamilyD dataInstD newtypeInstD tySynInstDclosedTypeFamilyDinfixLDinfixRDinfixND roleAnnotDstandaloneDerivWithStrategyD defaultSigDpatSynD patSynSigD pragCompleteDimplicitParamBindDkiSigDdefaultD typeDataDcxtnoSourceUnpackednesssourceNoUnpack sourceUnpacknoSourceStrictness sourceLazy sourceStrictnormalCrecCinfixCforallCgadtCrecGadtCbangbangType varBangTypeunidir implBidir explBidir prefixPatSyn infixPatSyn recordPatSynforallT forallVisTvarTconTtupleT unboxedTupleT unboxedSumTarrowTlistTappTappKindTsigT equalityTlitT promotedTpromotedTupleT promotedNilT promotedConsT wildCardTimplicitParamTinfixTnumTyLitstrTyLit charTyLitplainTVkindedTVnominalRrepresentationalRphantomRinferRstarK constraintKnoSigkindSigtyVarSiginjectivityAnncCallstdCallcApiprim javaScriptunsafesafefunDep mulArrowTtySynEqnruleVar typedRuleVar plainInvisTV kindedInvisTVvalueAnnotationtypeAnnotationmoduleAnnotation derivClause specifiedSpec inferredSpec stockStrategyanyclassStrategynewtypeStrategy viaStrategyrunQliftCode hoistCodebindCode bindCode_joinCodereport reportWarninglookupTypeNamelookupValueNamereify reifyFixity reifyTypenewDeclarationGroupreifyInstances reifyRolesreifyAnnotations reifyModulereifyConStrictness isInstancelocation isExtEnabled extsEnabledputDocgetDocnameBase nameModule namePackage nameSpace tupleDataName tupleTypeNameunboxedTupleDataNameunboxedTupleTypeNameunboxedSumDataNameunboxedSumTypeName maxPrecedence defaultFixitypprintpprExppprLitpprPat pprParendType bytesPrimLuInfixPparensPfromR fromThenRfromToR fromThenToRnormalGpatGparensEuInfixElam1E arithSeqEstringE instanceD pragLineDstandaloneDerivDuInfixTpromotedInfixTpromotedUInfixTparensTclassPequalPisStrict notStrictunpacked strictType varStrictTypevarKconKtupleKarrowKlistKappKappsE withDecDoc withDecsDocfunD_doc dataD_doc newtypeD_doc typeDataD_doc dataInstD_docnewtypeInstD_doc patSynD_docmkBytes Data.TypeableTypeRep showTyConTyConBoolIntOrdering listTyCon unitTyConmkFunTyData.Typeable.InternalTypeableData.Type.Equality:~~:HRefl:~:Refl Data.ProxyProxy tyConPackage tyConModule tyConNametyConFingerprintrnfTyContypeRepFingerprint trLiftedRep typeRepTyContypeReptypeOf rnfTypeRep showsTypeRepcasteqTheqTgcastgcast1gcast2 funResultTy splitTyConApp typeRepArgstypeOf1typeOf2typeOf3typeOf4typeOf5typeOf6typeOf7Show Data.DynamicDynamicGHC.Err undefinedshow unfoldTuple unfoldEnd showsPrecExprisTupleEq==/=Ord<=<False-:>varnames nonHoleVarscanonicalizeKeepingTruenot&&||GHC.Num+*-GHC.RealdivmodquotremnegateabssignumoddevenLTEQGT% ghc-bignumGHC.Num.IntegerIntegerGHC.EnumenumFrom enumFromTo enumFromThenenumFromThenTo