diff options
| author | aarne <aarne@chalmers.se> | 2009-06-22 15:39:08 +0000 |
|---|---|---|
| committer | aarne <aarne@chalmers.se> | 2009-06-22 15:39:08 +0000 |
| commit | e89fdae2fa1626348d8025824a7469252fa85e42 (patch) | |
| tree | c7d46bbd0494043b4bd6f917a25a7687517d0547 /old-lib/prelude | |
| parent | 3049b59b35b25381a7c6787444165c200d66e08b (diff) | |
next-lib renamed to lib, lib to old-lib
Diffstat (limited to 'old-lib/prelude')
| -rw-r--r-- | old-lib/prelude/Coordination.gf | 129 | ||||
| -rw-r--r-- | old-lib/prelude/Formal.gf | 54 | ||||
| -rw-r--r-- | old-lib/prelude/HTML.gf | 8 | ||||
| -rw-r--r-- | old-lib/prelude/Latex.gf | 12 | ||||
| -rw-r--r-- | old-lib/prelude/Precedence.gf | 117 | ||||
| -rw-r--r-- | old-lib/prelude/Predef.gf | 37 | ||||
| -rw-r--r-- | old-lib/prelude/PredefAbs.gf | 4 | ||||
| -rw-r--r-- | old-lib/prelude/PredefCnc.gf | 4 | ||||
| -rw-r--r-- | old-lib/prelude/Prelude.gf | 142 |
9 files changed, 507 insertions, 0 deletions
diff --git a/old-lib/prelude/Coordination.gf b/old-lib/prelude/Coordination.gf new file mode 100644 index 000000000..499b45306 --- /dev/null +++ b/old-lib/prelude/Coordination.gf @@ -0,0 +1,129 @@ +resource Coordination = open Prelude in { + +param + ListSize = TwoElem | ManyElem ; + +oper + ListX = {s1,s2 : Str} ; + + twoStr : (x,y : Str) -> ListX = \x,y -> + {s1 = x ; s2 = y} ; + consStr : Str -> ListX -> Str -> ListX = \comma,xs,x -> + {s1 = xs.s1 ++ comma ++ xs.s2 ; s2 = x } ; + + twoSS : (_,_ : SS) -> ListX = \x,y -> + twoStr x.s y.s ; + consSS : Str -> ListX -> SS -> ListX = \comma,xs,x -> + consStr comma xs x.s ; + + Conjunction : Type = SS ; + ConjunctionDistr : Type = {s1 : Str ; s2 : Str} ; + + conjunctX : Conjunction -> ListX -> Str = \or,xs -> + xs.s1 ++ or.s ++ xs.s2 ; + + conjunctDistrX : ConjunctionDistr -> ListX -> Str = \or,xs -> + or.s1 ++ xs.s1 ++ or.s2 ++ xs.s2 ; + + conjunctSS : Conjunction -> ListX -> SS = \or,xs -> + ss (xs.s1 ++ or.s ++ xs.s2) ; + + conjunctDistrSS : ConjunctionDistr -> ListX -> SS = \or,xs -> + ss (or.s1 ++ xs.s1 ++ or.s2 ++ xs.s2) ; + + -- all this lifted to tables + + ListTable : Type -> Type = \P -> {s1,s2 : P => Str} ; + + twoTable : (P : Type) -> (_,_ : {s : P => Str}) -> ListTable P = \_,x,y -> + {s1 = x.s ; s2 = y.s} ; + + consTable : (P : Type) -> Str -> ListTable P -> {s : P => Str} -> ListTable P = + \P,c,xs,x -> + {s1 = table P {o => xs.s1 ! o ++ c ++ xs.s2 ! o} ; s2 = x.s} ; + + conjunctTable : (P : Type) -> Conjunction -> ListTable P -> {s : P => Str} = + \P,or,xs -> + {s = table P {p => xs.s1 ! p ++ or.s ++ xs.s2 ! p}} ; + + conjunctDistrTable : + (P : Type) -> ConjunctionDistr -> ListTable P -> {s : P => Str} = \P,or,xs -> + {s = table P {p => or.s1++ xs.s1 ! p ++ or.s2 ++ xs.s2 ! p}} ; + + -- ... and to two- and three-argument tables: how clumsy! --- + + ListTable2 : Type -> Type -> Type = \P,Q -> + {s1,s2 : P => Q => Str} ; + + twoTable2 : (P,Q : Type) -> (_,_ : {s : P => Q => Str}) -> ListTable2 P Q = + \_,_,x,y -> + {s1 = x.s ; s2 = y.s} ; + + consTable2 : + (P,Q : Type) -> Str -> ListTable2 P Q -> {s : P => Q => Str} -> ListTable2 P Q = + \P,Q,c,xs,x -> + {s1 = table P {p => table Q {q => xs.s1 ! p ! q ++ c ++ xs.s2 ! p! q}} ; + s2 = x.s + } ; + + conjunctTable2 : + (P,Q : Type) -> Conjunction -> ListTable2 P Q -> {s : P => Q => Str} = + \P,Q,or,xs -> + {s = table P {p => table Q {q => xs.s1 ! p ! q ++ or.s ++ xs.s2 ! p ! q}}} ; + + conjunctDistrTable2 : + (P,Q : Type) -> ConjunctionDistr -> ListTable2 P Q -> {s : P => Q => Str} = + \P,Q,or,xs -> + {s = + table P {p => table Q {q => or.s1++ xs.s1 ! p ! q ++ or.s2 ++ xs.s2 ! p ! q}}} ; + + ListTable3 : Type -> Type -> Type -> Type = \P,Q,R -> + {s1,s2 : P => Q => R => Str} ; + + twoTable3 : (P,Q,R : Type) -> (_,_ : {s : P => Q => R => Str}) -> + ListTable3 P Q R = + \_,_,_,x,y -> + {s1 = x.s ; s2 = y.s} ; + + consTable3 : + (P,Q,R : Type) -> Str -> ListTable3 P Q R -> {s : P => Q => R => Str} -> + ListTable3 P Q R = + \P,Q,R,c,xs,x -> + {s1 = \\p,q,r => xs.s1 ! p ! q ! r ++ c ++ xs.s2 ! p ! q ! r ; + s2 = x.s + } ; + + conjunctTable3 : + (P,Q,R : Type) -> Conjunction -> ListTable3 P Q R -> {s : P => Q => R => Str} = + \P,Q,R,or,xs -> + {s = \\p,q,r => xs.s1 ! p ! q ! r ++ or.s ++ xs.s2 ! p ! q ! r} ; + + conjunctDistrTable3 : + (P,Q,R : Type) -> ConjunctionDistr -> ListTable3 P Q R -> + {s : P => Q => R => Str} = + \P,Q,R,or,xs -> + {s = \\p,q,r => or.s1++ xs.s1 ! p ! q ! r ++ or.s2 ++ xs.s2 ! p ! q ! r} ; + + comma = "," ; + +-- you can also do this to right-associative lists: + + consrStr : Str -> Str -> ListX -> ListX = \comma,x,xs -> + {s1 = x ++ comma ++ xs.s1 ; s2 = xs.s2 } ; + + consrSS : Str -> SS -> ListX -> ListX = \comma,x,xs -> + consrStr comma x.s xs ; + + consrTable : (P : Type) -> Str -> {s : P => Str} -> ListTable P -> ListTable P = + \P,c,x,xs -> + {s1 = table P {o => x.s ! o ++ c ++ xs.s1 ! o} ; s2 = xs.s2} ; + + consrTable2 : (P,Q : Type) -> Str -> {s : P => Q => Str} -> + ListTable2 P Q -> ListTable2 P Q = + \P,Q,c,x,xs -> + {s1 = table P {p => table Q {q => x.s ! p ! q ++ c ++ xs.s1 ! p ! q}} ; + s2 = xs.s2 + } ; + + +} ; diff --git a/old-lib/prelude/Formal.gf b/old-lib/prelude/Formal.gf new file mode 100644 index 000000000..2aa33d9ef --- /dev/null +++ b/old-lib/prelude/Formal.gf @@ -0,0 +1,54 @@ +resource Formal = open Prelude in { + +-- to replace the old library Precedence + + oper + Prec : PType ; + TermPrec : Type = {s : Str ; p : Prec} ; + + mkPrec : Prec -> Str -> TermPrec = \p,s -> + {s = s ; p = p} ; + + top : TermPrec -> Str = usePrec 0 ; + + constant : Str -> TermPrec = mkPrec highest ; + + infixl : Prec -> Str -> (_,_ : TermPrec) -> TermPrec = \p,f,x,y -> + mkPrec p (usePrec p x ++ f ++ usePrec (nextPrec p) y) ; + infixr : Prec -> Str -> (_,_ : TermPrec) -> TermPrec = \p,f,x,y -> + mkPrec p (usePrec (nextPrec p) x ++ f ++ usePrec p y) ; + infixn : Prec -> Str -> (_,_ : TermPrec) -> TermPrec = \p,f,x,y -> + mkPrec p (usePrec (nextPrec p) x ++ f ++ usePrec (nextPrec p) y) ; + +-- auxiliaries, should not be needed so much + + usePrec : Prec -> TermPrec -> Str = \p,x -> + case lessPrec x.p p of { + True => parenth x.s ; + False => parenthOpt x.s + } ; + + parenth : Str -> Str = \s -> "(" ++ s ++ ")" ; + parenthOpt : Str -> Str = \s -> variants {s ; "(" ++ s ++ ")"} ; + +--. +-- low-level things: don't use + + Prec : PType = Predef.Ints 4 ; + + highest = 4 ; + + lessPrec : Prec -> Prec -> Bool = \p,q -> + case <<p,q> : Prec * Prec> of { + <3,4> | <2,3> | <2,4> => True ; + <1,1> | <1,0> | <0,0> => False ; + <1,_> | <0,_> => True ; + _ => False + } ; + + nextPrec : Prec -> Prec = \p -> case <p : Prec> of { + 4 => 4 ; + n => Predef.plus n 1 + } ; + +} diff --git a/old-lib/prelude/HTML.gf b/old-lib/prelude/HTML.gf new file mode 100644 index 000000000..b469b582c --- /dev/null +++ b/old-lib/prelude/HTML.gf @@ -0,0 +1,8 @@ +resource HTML = open Prelude in { + oper + tag : Str -> Str = \t -> "<" + t + ">" ; + endtag : Str -> Str = \t -> tag ("/" + t) ; + intag : Str -> Str -> Str = \t,s -> tag t ++ s ++ endtag t ; + intagAttr : Str -> Str -> Str -> Str = + \t,a,s -> ("<" + t) ++ (a + ">") ++ s ++ endtag t ; +} diff --git a/old-lib/prelude/Latex.gf b/old-lib/prelude/Latex.gf new file mode 100644 index 000000000..2fd2f9ec8 --- /dev/null +++ b/old-lib/prelude/Latex.gf @@ -0,0 +1,12 @@ +resource Latex = open Prelude in { + oper + command : Str -> Str = \c -> "\\" + c ; + fun1 : Str -> Str -> Str = \f,x -> "\\" + f + "{" ++ x ++ "}" ; + fun2 : Str -> Str -> Str -> Str = + \f,x,y -> "\\" + f + "{" ++ x ++ "}{" ++ y ++ "}" ; + begin : Str -> Str = \e -> "\\begin{" + e + "}" ; + end : Str -> Str = \e -> "\\end{" + e + "}" ; + inEnv : Str -> Str -> Str = \e,s -> begin e ++ s ++ end e ; +} + + diff --git a/old-lib/prelude/Precedence.gf b/old-lib/prelude/Precedence.gf new file mode 100644 index 000000000..62775958c --- /dev/null +++ b/old-lib/prelude/Precedence.gf @@ -0,0 +1,117 @@ +-- operations for precedence-dependent strings. +-- five levels: +-- p4 (constants), p3 (applications), p2 (products), p1 (sums), p0 (arrows) + +resource Precedence = open Prelude in { + +param +Prec = p4 | p3 | p2 | p1 | p0 ; + +oper +PrecTerm = Prec => Str ; + +oper +pss : PrecTerm -> {s : PrecTerm} = \s -> {s = s} ; + + +-- change this if you want some other type of parentheses +mkParenth : Str -> Str = \str -> "(" ++ str ++ ")" ; + +-- define ordering of precedences +nextPrec : Prec => Prec = + table {p0 => p1 ; p1 => p2 ; p2 => p3 ; _ => p4} ; +prevPrec : Prec => Prec = + table {p4 => p3 ; p3 => p2 ; p2 => p1 ; _ => p0} ; + +mkPrec : Str -> Prec => Prec => Str = \str -> + table { + p4 => table { -- use the term of precedence p4... + _ => str} ; -- ...always without parentheses + p3 => table { -- use the term of precedence p3... + p4 => mkParenth str ; -- ...in parentheses if p4 is required... + _ => str} ; -- ...otherwise without parentheses + p2 => table { + p4 => mkParenth str ; + p3 => mkParenth str ; + _ => str} ; + p1 => table { + p1 => str ; + p0 => str ; + _ => mkParenth str} ; + p0 => table { + p0 => str ; + _ => mkParenth str} + } ; + +-- make a string into a constant, of precedence p4 +mkConst : Str -> PrecTerm = + \f -> + mkPrec f ! p4 ; + +-- make a string into a 1/2/3 -place prefix operator, of precedence p3 +mkFun1 : Str -> PrecTerm -> PrecTerm = + \f -> \x -> + table {k => mkPrec (f ++ x ! p4) ! p3 ! k} ; +mkFun2 : Str -> PrecTerm -> PrecTerm -> PrecTerm = + \f -> \x -> \y -> + table {k => mkPrec (f ++ x ! p4 ++ y ! p4) ! p3 ! k} ; +mkFun3 : Str -> PrecTerm -> PrecTerm -> PrecTerm -> PrecTerm = + \f -> \x -> \y -> \z -> + table {k => mkPrec (f ++ x ! p4 ++ y ! p4 ++ z ! p4) ! p3 ! k} ; + +-- make a string into a non/left/right -associative infix operator, of precedence p +mkInfix : Str -> Prec -> PrecTerm -> PrecTerm -> PrecTerm = + \f -> \p -> \x -> \y -> + table {k => mkPrec (x ! (nextPrec ! p) ++ f ++ y ! (nextPrec ! p)) ! p ! k} ; +mkInfixL : Str -> Prec -> PrecTerm -> PrecTerm -> PrecTerm = + \f -> \p -> \x -> \y -> + table {k => mkPrec (x ! p ++ f ++ y ! (nextPrec ! p)) ! p ! k} ; +mkInfixR : Str -> Prec -> PrecTerm -> PrecTerm -> PrecTerm = + \f -> \p -> \x -> \y -> + table {k => mkPrec (x ! (nextPrec ! p) ++ f ++ y ! p) ! p ! k} ; + +----------------------------------------------------------- + +-- alternative: +-- precedence as inherent feature + +oper TermWithPrec = {s : Str ; p : Prec} ; + +oper +mkpPrec : Str -> Prec -> TermWithPrec = + \f -> \p -> + {s = f ; p = p} ; + +usePrec : TermWithPrec -> Prec -> Str = + \x -> \p -> + mkPrec x.s ! x.p ! p ; + +-- make a string into a constant, of precedence p4 +mkpConst : Str -> TermWithPrec = + \f -> + mkpPrec f p4 ; + +-- make a string into a 1/2/3 -place prefix operator, of precedence p3 +mkpFun1 : Str -> TermWithPrec -> TermWithPrec = + \f -> \x -> + mkpPrec (f ++ usePrec x p4) p3 ; + +mkpFun2 : Str -> TermWithPrec -> TermWithPrec -> TermWithPrec = + \f -> \x -> \y -> + mkpPrec (f ++ usePrec x p4 ++ usePrec y p4) p3 ; + +mkpFun3 : Str -> TermWithPrec -> TermWithPrec -> TermWithPrec -> TermWithPrec = + \f -> \x -> \y -> \z -> + mkpPrec (f ++ usePrec x p4 ++ usePrec y p4 ++ usePrec z p4) p3 ; + +-- make a string a into non/left/right -associative infix operator, of precedence p +mkpInfix : Str -> Prec -> TermWithPrec -> TermWithPrec -> TermWithPrec = + \f -> \p -> \x -> \y -> + mkpPrec (usePrec x (nextPrec ! p) ++ f ++ usePrec y (nextPrec ! p)) p ; +mkpInfixL : Str -> Prec -> TermWithPrec -> TermWithPrec -> TermWithPrec = + \f -> \p -> \x -> \y -> + mkpPrec (usePrec x p ++ f ++ usePrec y (nextPrec ! p)) p ; +mkpInfixR : Str -> Prec -> TermWithPrec -> TermWithPrec -> TermWithPrec = + \f -> \p -> \x -> \y -> + mkpPrec (usePrec x (nextPrec ! p) ++ f ++ usePrec y p) p ; +} ;
\ No newline at end of file diff --git a/old-lib/prelude/Predef.gf b/old-lib/prelude/Predef.gf new file mode 100644 index 000000000..d8141ea8c --- /dev/null +++ b/old-lib/prelude/Predef.gf @@ -0,0 +1,37 @@ +--1 Predefined functions for concrete syntax + +-- The definitions of these constants are hard-coded in GF, and defined +-- in [AppPredefined.hs ../src/GF/Grammar/AppPredefined.hs]. Applying +-- them to run-time variables leads to compiler errors that are often +-- only detected at the code generation time. + +resource Predef = { + +-- This type of booleans is for internal use only. + + param PBool = PTrue | PFalse ; + + oper Error : Type = variants {} ; -- the empty type + oper Int : Type = variants {} ; -- the type of integers + oper Ints : Int -> Type = variants {} ; -- the type of integers from 0 to n + + oper error : Str -> Error = variants {} ; -- forms error message + oper length : Tok -> Int = variants {} ; -- length of string + oper drop : Int -> Tok -> Tok = variants {} ; -- drop prefix of length + oper take : Int -> Tok -> Tok = variants {} ; -- take prefix of length + oper tk : Int -> Tok -> Tok = variants {} ; -- drop suffix of length + oper dp : Int -> Tok -> Tok = variants {} ; -- take suffix of length + oper eqInt : Int -> Int -> PBool = variants {} ; -- test if equal integers + oper lessInt: Int -> Int -> PBool = variants {} ; -- test order of integers + oper plus : Int -> Int -> Int = variants {} ; -- add integers + oper eqStr : Tok -> Tok -> PBool = variants {} ; -- test if equal strings + oper occur : Tok -> Tok -> PBool = variants {} ; -- test if occurs as substring + oper occurs : Tok -> Tok -> PBool = variants {} ; -- test if any char occurs + oper show : (P : Type) -> P -> Tok = variants {} ; -- convert param to string + oper read : (P : Type) -> Tok -> P = variants {} ; -- convert string to param + oper toStr : (L : Type) -> L -> Str = variants {} ; -- find the "first" string + oper mapStr : (L : Type) -> (Str -> Str) -> L -> L = variants {} ; + -- map all strings in a data structure; experimental --- + +} ; + diff --git a/old-lib/prelude/PredefAbs.gf b/old-lib/prelude/PredefAbs.gf new file mode 100644 index 000000000..a99961d00 --- /dev/null +++ b/old-lib/prelude/PredefAbs.gf @@ -0,0 +1,4 @@ +abstract PredefAbs = { + cat Int ; String ; Float ; +} ; + diff --git a/old-lib/prelude/PredefCnc.gf b/old-lib/prelude/PredefCnc.gf new file mode 100644 index 000000000..f12b9b1f0 --- /dev/null +++ b/old-lib/prelude/PredefCnc.gf @@ -0,0 +1,4 @@ +concrete PredefCnc of PredefAbs = { + lincat + Int, Float, String = {s : Str} ; +} ; diff --git a/old-lib/prelude/Prelude.gf b/old-lib/prelude/Prelude.gf new file mode 100644 index 000000000..56545d051 --- /dev/null +++ b/old-lib/prelude/Prelude.gf @@ -0,0 +1,142 @@ +--1 The GF Prelude + +-- This file defines some prelude facilities usable in all grammars. + +resource Prelude = open (Predef=Predef) in { + +oper + +--2 Strings, records, and tables + + SS : Type = {s : Str} ; + ss : Str -> SS = \s -> {s = s} ; + ss2 : (_,_ : Str) -> SS = \x,y -> ss (x ++ y) ; + ss3 : (_,_ ,_: Str) -> SS = \x,y,z -> ss (x ++ y ++ z) ; + + cc2 : (_,_ : SS) -> SS = \x,y -> ss (x.s ++ y.s) ; + cc3 : (_,_,_ : SS) -> SS = \x,y,z -> ss (x.s ++ y.s ++ z.s) ; + + SS1 : Type -> Type = \P -> {s : P => Str} ; + ss1 : (A : Type) -> Str -> SS1 A = \A,s -> {s = table {_ => s}} ; + + SP1 : Type -> Type = \P -> {s : Str ; p : P} ; + sp1 : (A : Type) -> Str -> A -> SP1 A = \_,s,a -> {s = s ; p = a} ; + + constTable : (A,B : Type) -> B -> A => B = \_,_,b -> \\_ => b ; + constStr : (A : Type) -> Str -> A => Str = \A -> constTable A Str ; + +-- Discontinuous constituents. + + SD2 : Type = {s1,s2 : Str} ; + sd2 : (_,_ : Str) -> SD2 = \x,y -> {s1 = x ; s2 = y} ; + + +--2 Optional elements + +-- Missing form. + + nonExist : Str = variants {} ; + +-- Optional string with preference on the string vs. empty. + + optStr : Str -> Str = \s -> variants {s ; []} ; + strOpt : Str -> Str = \s -> variants {[] ; s} ; + +-- Free order between two strings. + + bothWays : Str -> Str -> Str = \x,y -> variants {x ++ y ; y ++ x} ; + +-- Parametric order between two strings. + + preOrPost : Bool -> Str -> Str -> Str = \pr,x,y -> + if_then_Str pr (x ++ y) (y ++ x) ; + +--2 Infixes. prefixes, and postfixes + +-- Fixes with precedences are defined in [Precedence Precedence.html]. + + infixSS : Str -> SS -> SS -> SS = \f,x,y -> ss (x.s ++ f ++ y.s) ; + prefixSS : Str -> SS -> SS = \f,x -> ss (f ++ x.s) ; + postfixSS : Str -> SS -> SS = \f,x -> ss (x.s ++ f) ; + embedSS : Str -> Str -> SS -> SS = \f,g,x -> ss (f ++ x.s ++ g) ; + + +--2 Booleans + + param Bool = True | False ; + +oper + if_then_else : (A : Type) -> Bool -> A -> A -> A = \_,c,d,e -> + case c of { + True => d ; ---- should not need to qualify + False => e + } ; + + andB : (_,_ : Bool) -> Bool = \a,b -> if_then_else Bool a b False ; + orB : (_,_ : Bool) -> Bool = \a,b -> if_then_else Bool a True b ; + notB : Bool -> Bool = \a -> if_then_else Bool a False True ; + + if_then_Str : Bool -> Str -> Str -> Str = if_then_else Str ; + + onlyIf : Bool -> Str -> Str = \b,s -> case b of { + True => s ; + _ => nonExist + } ; + +-- Interface to internal booleans + + pbool2bool : Predef.PBool -> Bool = \b -> case b of { + Predef.PFalse => False ; Predef.PTrue => True + } ; + + init : Tok -> Tok = Predef.tk 1 ; + last : Tok -> Tok = Predef.dp 1 ; + +--2 High-level acces to Predef operations + + isNil : Tok -> Bool = \b -> pbool2bool (Predef.eqStr [] b) ; + + ifTok : (A : Type) -> Tok -> Tok -> A -> A -> A = \A,t,u,a,b -> + case Predef.eqStr t u of {Predef.PTrue => a ; Predef.PFalse => b} ; + +--2 Lexer-related operations + +-- Bind together two tokens in some lexers, either obligatorily or optionally + + oper + glue : Str -> Str -> Str = \x,y -> x ++ BIND ++ y ; + glueOpt : Str -> Str -> Str = \x,y -> variants {glue x y ; x ++ y} ; + noglueOpt : Str -> Str -> Str = \x,y -> variants {x ++ y ; glue x y} ; + +-- Force capitalization of next word in some unlexers + + capitalize : Str -> Str = \s -> CAPIT ++ s ; + +-- These should be hidden, and never changed since they are hardcoded in (un)lexers + + BIND : Str = "&+" ; + PARA : Str = "&-" ; + CAPIT : Str = "&|" ; + +--2 Miscellaneous + +-- Identity function + + id : (A : Type) -> A -> A = \_,a -> a ; + +-- Parentheses + + paren : Str -> Str = \s -> "(" ++ s ++ ")" ; + parenss : SS -> SS = \s -> ss (paren s.s) ; + +-- Zero, one, two, or more (elements in a list etc) + +param + ENumber = E0 | E1 | E2 | Emore ; + +oper + eNext : ENumber -> ENumber = \e -> case e of { + E0 => E1 ; E1 => E2 ; _ => Emore} ; + + +} |
