Implement roles into Template Haskell.
[ghc.git] / libraries / template-haskell / Language / Haskell / TH / Lib.hs
1 -- |
2 -- TH.Lib contains lots of useful helper functions for
3 -- generating and manipulating Template Haskell terms
4
5 module Language.Haskell.TH.Lib where
6 -- All of the exports from this module should
7 -- be "public" functions. The main module TH
8 -- re-exports them all.
9
10 import Language.Haskell.TH.Syntax
11 import Control.Monad( liftM, liftM2 )
12 import Data.Word( Word8 )
13
14 ----------------------------------------------------------
15 -- * Type synonyms
16 ----------------------------------------------------------
17
18 type InfoQ = Q Info
19 type PatQ = Q Pat
20 type FieldPatQ = Q FieldPat
21 type ExpQ = Q Exp
22 type DecQ = Q Dec
23 type DecsQ = Q [Dec]
24 type ConQ = Q Con
25 type TypeQ = Q Type
26 type TyLitQ = Q TyLit
27 type CxtQ = Q Cxt
28 type PredQ = Q Pred
29 type MatchQ = Q Match
30 type ClauseQ = Q Clause
31 type BodyQ = Q Body
32 type GuardQ = Q Guard
33 type StmtQ = Q Stmt
34 type RangeQ = Q Range
35 type StrictTypeQ = Q StrictType
36 type VarStrictTypeQ = Q VarStrictType
37 type FieldExpQ = Q FieldExp
38 type RuleBndrQ = Q RuleBndr
39 type TySynEqnQ = Q TySynEqn
40
41 ----------------------------------------------------------
42 -- * Lowercase pattern syntax functions
43 ----------------------------------------------------------
44
45 intPrimL :: Integer -> Lit
46 intPrimL = IntPrimL
47 wordPrimL :: Integer -> Lit
48 wordPrimL = WordPrimL
49 floatPrimL :: Rational -> Lit
50 floatPrimL = FloatPrimL
51 doublePrimL :: Rational -> Lit
52 doublePrimL = DoublePrimL
53 integerL :: Integer -> Lit
54 integerL = IntegerL
55 charL :: Char -> Lit
56 charL = CharL
57 stringL :: String -> Lit
58 stringL = StringL
59 stringPrimL :: [Word8] -> Lit
60 stringPrimL = StringPrimL
61 rationalL :: Rational -> Lit
62 rationalL = RationalL
63
64 litP :: Lit -> PatQ
65 litP l = return (LitP l)
66 varP :: Name -> PatQ
67 varP v = return (VarP v)
68 tupP :: [PatQ] -> PatQ
69 tupP ps = do { ps1 <- sequence ps; return (TupP ps1)}
70 unboxedTupP :: [PatQ] -> PatQ
71 unboxedTupP ps = do { ps1 <- sequence ps; return (UnboxedTupP ps1)}
72 conP :: Name -> [PatQ] -> PatQ
73 conP n ps = do ps' <- sequence ps
74 return (ConP n ps')
75 infixP :: PatQ -> Name -> PatQ -> PatQ
76 infixP p1 n p2 = do p1' <- p1
77 p2' <- p2
78 return (InfixP p1' n p2')
79 uInfixP :: PatQ -> Name -> PatQ -> PatQ
80 uInfixP p1 n p2 = do p1' <- p1
81 p2' <- p2
82 return (UInfixP p1' n p2')
83 parensP :: PatQ -> PatQ
84 parensP p = do p' <- p
85 return (ParensP p')
86
87 tildeP :: PatQ -> PatQ
88 tildeP p = do p' <- p
89 return (TildeP p')
90 bangP :: PatQ -> PatQ
91 bangP p = do p' <- p
92 return (BangP p')
93 asP :: Name -> PatQ -> PatQ
94 asP n p = do p' <- p
95 return (AsP n p')
96 wildP :: PatQ
97 wildP = return WildP
98 recP :: Name -> [FieldPatQ] -> PatQ
99 recP n fps = do fps' <- sequence fps
100 return (RecP n fps')
101 listP :: [PatQ] -> PatQ
102 listP ps = do ps' <- sequence ps
103 return (ListP ps')
104 sigP :: PatQ -> TypeQ -> PatQ
105 sigP p t = do p' <- p
106 t' <- t
107 return (SigP p' t')
108 viewP :: ExpQ -> PatQ -> PatQ
109 viewP e p = do e' <- e
110 p' <- p
111 return (ViewP e' p')
112
113 fieldPat :: Name -> PatQ -> FieldPatQ
114 fieldPat n p = do p' <- p
115 return (n, p')
116
117
118 -------------------------------------------------------------------------------
119 -- * Stmt
120
121 bindS :: PatQ -> ExpQ -> StmtQ
122 bindS p e = liftM2 BindS p e
123
124 letS :: [DecQ] -> StmtQ
125 letS ds = do { ds1 <- sequence ds; return (LetS ds1) }
126
127 noBindS :: ExpQ -> StmtQ
128 noBindS e = do { e1 <- e; return (NoBindS e1) }
129
130 parS :: [[StmtQ]] -> StmtQ
131 parS _ = fail "No parallel comprehensions yet"
132
133 -------------------------------------------------------------------------------
134 -- * Range
135
136 fromR :: ExpQ -> RangeQ
137 fromR x = do { a <- x; return (FromR a) }
138
139 fromThenR :: ExpQ -> ExpQ -> RangeQ
140 fromThenR x y = do { a <- x; b <- y; return (FromThenR a b) }
141
142 fromToR :: ExpQ -> ExpQ -> RangeQ
143 fromToR x y = do { a <- x; b <- y; return (FromToR a b) }
144
145 fromThenToR :: ExpQ -> ExpQ -> ExpQ -> RangeQ
146 fromThenToR x y z = do { a <- x; b <- y; c <- z;
147 return (FromThenToR a b c) }
148 -------------------------------------------------------------------------------
149 -- * Body
150
151 normalB :: ExpQ -> BodyQ
152 normalB e = do { e1 <- e; return (NormalB e1) }
153
154 guardedB :: [Q (Guard,Exp)] -> BodyQ
155 guardedB ges = do { ges' <- sequence ges; return (GuardedB ges') }
156
157 -------------------------------------------------------------------------------
158 -- * Guard
159
160 normalG :: ExpQ -> GuardQ
161 normalG e = do { e1 <- e; return (NormalG e1) }
162
163 normalGE :: ExpQ -> ExpQ -> Q (Guard, Exp)
164 normalGE g e = do { g1 <- g; e1 <- e; return (NormalG g1, e1) }
165
166 patG :: [StmtQ] -> GuardQ
167 patG ss = do { ss' <- sequence ss; return (PatG ss') }
168
169 patGE :: [StmtQ] -> ExpQ -> Q (Guard, Exp)
170 patGE ss e = do { ss' <- sequence ss;
171 e' <- e;
172 return (PatG ss', e') }
173
174 -------------------------------------------------------------------------------
175 -- * Match and Clause
176
177 -- | Use with 'caseE'
178 match :: PatQ -> BodyQ -> [DecQ] -> MatchQ
179 match p rhs ds = do { p' <- p;
180 r' <- rhs;
181 ds' <- sequence ds;
182 return (Match p' r' ds') }
183
184 -- | Use with 'funD'
185 clause :: [PatQ] -> BodyQ -> [DecQ] -> ClauseQ
186 clause ps r ds = do { ps' <- sequence ps;
187 r' <- r;
188 ds' <- sequence ds;
189 return (Clause ps' r' ds') }
190
191
192 ---------------------------------------------------------------------------
193 -- * Exp
194
195 -- | Dynamically binding a variable (unhygenic)
196 dyn :: String -> Q Exp
197 dyn s = return (VarE (mkName s))
198
199 global :: Name -> ExpQ
200 global s = return (VarE s)
201
202 varE :: Name -> ExpQ
203 varE s = return (VarE s)
204
205 conE :: Name -> ExpQ
206 conE s = return (ConE s)
207
208 litE :: Lit -> ExpQ
209 litE c = return (LitE c)
210
211 appE :: ExpQ -> ExpQ -> ExpQ
212 appE x y = do { a <- x; b <- y; return (AppE a b)}
213
214 parensE :: ExpQ -> ExpQ
215 parensE x = do { x' <- x; return (ParensE x') }
216
217 uInfixE :: ExpQ -> ExpQ -> ExpQ -> ExpQ
218 uInfixE x s y = do { x' <- x; s' <- s; y' <- y;
219 return (UInfixE x' s' y') }
220
221 infixE :: Maybe ExpQ -> ExpQ -> Maybe ExpQ -> ExpQ
222 infixE (Just x) s (Just y) = do { a <- x; s' <- s; b <- y;
223 return (InfixE (Just a) s' (Just b))}
224 infixE Nothing s (Just y) = do { s' <- s; b <- y;
225 return (InfixE Nothing s' (Just b))}
226 infixE (Just x) s Nothing = do { a <- x; s' <- s;
227 return (InfixE (Just a) s' Nothing)}
228 infixE Nothing s Nothing = do { s' <- s; return (InfixE Nothing s' Nothing) }
229
230 infixApp :: ExpQ -> ExpQ -> ExpQ -> ExpQ
231 infixApp x y z = infixE (Just x) y (Just z)
232 sectionL :: ExpQ -> ExpQ -> ExpQ
233 sectionL x y = infixE (Just x) y Nothing
234 sectionR :: ExpQ -> ExpQ -> ExpQ
235 sectionR x y = infixE Nothing x (Just y)
236
237 lamE :: [PatQ] -> ExpQ -> ExpQ
238 lamE ps e = do ps' <- sequence ps
239 e' <- e
240 return (LamE ps' e')
241
242 -- | Single-arg lambda
243 lam1E :: PatQ -> ExpQ -> ExpQ
244 lam1E p e = lamE [p] e
245
246 lamCaseE :: [MatchQ] -> ExpQ
247 lamCaseE ms = sequence ms >>= return . LamCaseE
248
249 tupE :: [ExpQ] -> ExpQ
250 tupE es = do { es1 <- sequence es; return (TupE es1)}
251
252 unboxedTupE :: [ExpQ] -> ExpQ
253 unboxedTupE es = do { es1 <- sequence es; return (UnboxedTupE es1)}
254
255 condE :: ExpQ -> ExpQ -> ExpQ -> ExpQ
256 condE x y z = do { a <- x; b <- y; c <- z; return (CondE a b c)}
257
258 multiIfE :: [Q (Guard, Exp)] -> ExpQ
259 multiIfE alts = sequence alts >>= return . MultiIfE
260
261 letE :: [DecQ] -> ExpQ -> ExpQ
262 letE ds e = do { ds2 <- sequence ds; e2 <- e; return (LetE ds2 e2) }
263
264 caseE :: ExpQ -> [MatchQ] -> ExpQ
265 caseE e ms = do { e1 <- e; ms1 <- sequence ms; return (CaseE e1 ms1) }
266
267 doE :: [StmtQ] -> ExpQ
268 doE ss = do { ss1 <- sequence ss; return (DoE ss1) }
269
270 compE :: [StmtQ] -> ExpQ
271 compE ss = do { ss1 <- sequence ss; return (CompE ss1) }
272
273 arithSeqE :: RangeQ -> ExpQ
274 arithSeqE r = do { r' <- r; return (ArithSeqE r') }
275
276 listE :: [ExpQ] -> ExpQ
277 listE es = do { es1 <- sequence es; return (ListE es1) }
278
279 sigE :: ExpQ -> TypeQ -> ExpQ
280 sigE e t = do { e1 <- e; t1 <- t; return (SigE e1 t1) }
281
282 recConE :: Name -> [Q (Name,Exp)] -> ExpQ
283 recConE c fs = do { flds <- sequence fs; return (RecConE c flds) }
284
285 recUpdE :: ExpQ -> [Q (Name,Exp)] -> ExpQ
286 recUpdE e fs = do { e1 <- e; flds <- sequence fs; return (RecUpdE e1 flds) }
287
288 stringE :: String -> ExpQ
289 stringE = litE . stringL
290
291 fieldExp :: Name -> ExpQ -> Q (Name, Exp)
292 fieldExp s e = do { e' <- e; return (s,e') }
293
294 -- ** 'arithSeqE' Shortcuts
295 fromE :: ExpQ -> ExpQ
296 fromE x = do { a <- x; return (ArithSeqE (FromR a)) }
297
298 fromThenE :: ExpQ -> ExpQ -> ExpQ
299 fromThenE x y = do { a <- x; b <- y; return (ArithSeqE (FromThenR a b)) }
300
301 fromToE :: ExpQ -> ExpQ -> ExpQ
302 fromToE x y = do { a <- x; b <- y; return (ArithSeqE (FromToR a b)) }
303
304 fromThenToE :: ExpQ -> ExpQ -> ExpQ -> ExpQ
305 fromThenToE x y z = do { a <- x; b <- y; c <- z;
306 return (ArithSeqE (FromThenToR a b c)) }
307
308
309 -------------------------------------------------------------------------------
310 -- * Dec
311
312 valD :: PatQ -> BodyQ -> [DecQ] -> DecQ
313 valD p b ds =
314 do { p' <- p
315 ; ds' <- sequence ds
316 ; b' <- b
317 ; return (ValD p' b' ds')
318 }
319
320 funD :: Name -> [ClauseQ] -> DecQ
321 funD nm cs =
322 do { cs1 <- sequence cs
323 ; return (FunD nm cs1)
324 }
325
326 tySynD :: Name -> [TyVarBndr] -> TypeQ -> DecQ
327 tySynD tc tvs rhs = do { rhs1 <- rhs; return (TySynD tc tvs rhs1) }
328
329 dataD :: CxtQ -> Name -> [TyVarBndr] -> [ConQ] -> [Name] -> DecQ
330 dataD ctxt tc tvs cons derivs =
331 do
332 ctxt1 <- ctxt
333 cons1 <- sequence cons
334 return (DataD ctxt1 tc tvs cons1 derivs)
335
336 newtypeD :: CxtQ -> Name -> [TyVarBndr] -> ConQ -> [Name] -> DecQ
337 newtypeD ctxt tc tvs con derivs =
338 do
339 ctxt1 <- ctxt
340 con1 <- con
341 return (NewtypeD ctxt1 tc tvs con1 derivs)
342
343 classD :: CxtQ -> Name -> [TyVarBndr] -> [FunDep] -> [DecQ] -> DecQ
344 classD ctxt cls tvs fds decs =
345 do
346 decs1 <- sequence decs
347 ctxt1 <- ctxt
348 return $ ClassD ctxt1 cls tvs fds decs1
349
350 instanceD :: CxtQ -> TypeQ -> [DecQ] -> DecQ
351 instanceD ctxt ty decs =
352 do
353 ctxt1 <- ctxt
354 decs1 <- sequence decs
355 ty1 <- ty
356 return $ InstanceD ctxt1 ty1 decs1
357
358 sigD :: Name -> TypeQ -> DecQ
359 sigD fun ty = liftM (SigD fun) $ ty
360
361 forImpD :: Callconv -> Safety -> String -> Name -> TypeQ -> DecQ
362 forImpD cc s str n ty
363 = do ty' <- ty
364 return $ ForeignD (ImportF cc s str n ty')
365
366 infixLD :: Int -> Name -> DecQ
367 infixLD prec nm = return (InfixD (Fixity prec InfixL) nm)
368
369 infixRD :: Int -> Name -> DecQ
370 infixRD prec nm = return (InfixD (Fixity prec InfixR) nm)
371
372 infixND :: Int -> Name -> DecQ
373 infixND prec nm = return (InfixD (Fixity prec InfixN) nm)
374
375 pragInlD :: Name -> Inline -> RuleMatch -> Phases -> DecQ
376 pragInlD name inline rm phases
377 = return $ PragmaD $ InlineP name inline rm phases
378
379 pragSpecD :: Name -> TypeQ -> Phases -> DecQ
380 pragSpecD n ty phases
381 = do
382 ty1 <- ty
383 return $ PragmaD $ SpecialiseP n ty1 Nothing phases
384
385 pragSpecInlD :: Name -> TypeQ -> Inline -> Phases -> DecQ
386 pragSpecInlD n ty inline phases
387 = do
388 ty1 <- ty
389 return $ PragmaD $ SpecialiseP n ty1 (Just inline) phases
390
391 pragSpecInstD :: TypeQ -> DecQ
392 pragSpecInstD ty
393 = do
394 ty1 <- ty
395 return $ PragmaD $ SpecialiseInstP ty1
396
397 pragRuleD :: String -> [RuleBndrQ] -> ExpQ -> ExpQ -> Phases -> DecQ
398 pragRuleD n bndrs lhs rhs phases
399 = do
400 bndrs1 <- sequence bndrs
401 lhs1 <- lhs
402 rhs1 <- rhs
403 return $ PragmaD $ RuleP n bndrs1 lhs1 rhs1 phases
404
405 familyNoKindD :: FamFlavour -> Name -> [TyVarBndr] -> DecQ
406 familyNoKindD flav tc tvs = return $ FamilyD flav tc tvs Nothing
407
408 familyKindD :: FamFlavour -> Name -> [TyVarBndr] -> Kind -> DecQ
409 familyKindD flav tc tvs k = return $ FamilyD flav tc tvs (Just k)
410
411 dataInstD :: CxtQ -> Name -> [TypeQ] -> [ConQ] -> [Name] -> DecQ
412 dataInstD ctxt tc tys cons derivs =
413 do
414 ctxt1 <- ctxt
415 tys1 <- sequence tys
416 cons1 <- sequence cons
417 return (DataInstD ctxt1 tc tys1 cons1 derivs)
418
419 newtypeInstD :: CxtQ -> Name -> [TypeQ] -> ConQ -> [Name] -> DecQ
420 newtypeInstD ctxt tc tys con derivs =
421 do
422 ctxt1 <- ctxt
423 tys1 <- sequence tys
424 con1 <- con
425 return (NewtypeInstD ctxt1 tc tys1 con1 derivs)
426
427 tySynInstD :: Name -> TySynEqnQ -> DecQ
428 tySynInstD tc eqn =
429 do
430 eqn1 <- eqn
431 return (TySynInstD tc eqn1)
432
433 closedTypeFamilyNoKindD :: Name -> [TyVarBndr] -> [TySynEqnQ] -> DecQ
434 closedTypeFamilyNoKindD tc tvs eqns =
435 do
436 eqns1 <- sequence eqns
437 return (ClosedTypeFamilyD tc tvs Nothing eqns1)
438
439 closedTypeFamilyKindD :: Name -> [TyVarBndr] -> Kind -> [TySynEqnQ] -> DecQ
440 closedTypeFamilyKindD tc tvs kind eqns =
441 do
442 eqns1 <- sequence eqns
443 return (ClosedTypeFamilyD tc tvs (Just kind) eqns1)
444
445 tySynEqn :: [TypeQ] -> TypeQ -> TySynEqnQ
446 tySynEqn lhs rhs =
447 do
448 lhs1 <- sequence lhs
449 rhs1 <- rhs
450 return (TySynEqn lhs1 rhs1)
451
452 cxt :: [PredQ] -> CxtQ
453 cxt = sequence
454
455 classP :: Name -> [TypeQ] -> PredQ
456 classP cla tys
457 = do
458 tys1 <- sequence tys
459 return (ClassP cla tys1)
460
461 equalP :: TypeQ -> TypeQ -> PredQ
462 equalP tleft tright
463 = do
464 tleft1 <- tleft
465 tright1 <- tright
466 return (EqualP tleft1 tright1)
467
468 normalC :: Name -> [StrictTypeQ] -> ConQ
469 normalC con strtys = liftM (NormalC con) $ sequence strtys
470
471 recC :: Name -> [VarStrictTypeQ] -> ConQ
472 recC con varstrtys = liftM (RecC con) $ sequence varstrtys
473
474 infixC :: Q (Strict, Type) -> Name -> Q (Strict, Type) -> ConQ
475 infixC st1 con st2 = do st1' <- st1
476 st2' <- st2
477 return $ InfixC st1' con st2'
478
479 forallC :: [TyVarBndr] -> CxtQ -> ConQ -> ConQ
480 forallC ns ctxt con = liftM2 (ForallC ns) ctxt con
481
482
483 -------------------------------------------------------------------------------
484 -- * Type
485
486 forallT :: [TyVarBndr] -> CxtQ -> TypeQ -> TypeQ
487 forallT tvars ctxt ty = do
488 ctxt1 <- ctxt
489 ty1 <- ty
490 return $ ForallT tvars ctxt1 ty1
491
492 varT :: Name -> TypeQ
493 varT = return . VarT
494
495 conT :: Name -> TypeQ
496 conT = return . ConT
497
498 appT :: TypeQ -> TypeQ -> TypeQ
499 appT t1 t2 = do
500 t1' <- t1
501 t2' <- t2
502 return $ AppT t1' t2'
503
504 arrowT :: TypeQ
505 arrowT = return ArrowT
506
507 listT :: TypeQ
508 listT = return ListT
509
510 litT :: TyLitQ -> TypeQ
511 litT l = fmap LitT l
512
513 tupleT :: Int -> TypeQ
514 tupleT i = return (TupleT i)
515
516 unboxedTupleT :: Int -> TypeQ
517 unboxedTupleT i = return (UnboxedTupleT i)
518
519 sigT :: TypeQ -> Kind -> TypeQ
520 sigT t k
521 = do
522 t' <- t
523 return $ SigT t' k
524
525 promotedT :: Name -> TypeQ
526 promotedT = return . PromotedT
527
528 promotedTupleT :: Int -> TypeQ
529 promotedTupleT i = return (PromotedTupleT i)
530
531 promotedNilT :: TypeQ
532 promotedNilT = return PromotedNilT
533
534 promotedConsT :: TypeQ
535 promotedConsT = return PromotedConsT
536
537 isStrict, notStrict, unpacked :: Q Strict
538 isStrict = return $ IsStrict
539 notStrict = return $ NotStrict
540 unpacked = return Unpacked
541
542 strictType :: Q Strict -> TypeQ -> StrictTypeQ
543 strictType = liftM2 (,)
544
545 varStrictType :: Name -> StrictTypeQ -> VarStrictTypeQ
546 varStrictType v st = do (s, t) <- st
547 return (v, s, t)
548
549 -- * Type Literals
550
551 numTyLit :: Integer -> TyLitQ
552 numTyLit n = if n >= 0 then return (NumTyLit n)
553 else fail ("Negative type-level number: " ++ show n)
554
555 strTyLit :: String -> TyLitQ
556 strTyLit s = return (StrTyLit s)
557
558
559
560 -------------------------------------------------------------------------------
561 -- * Kind
562
563 plainTV :: Name -> TyVarBndr
564 plainTV = PlainTV
565
566 kindedTV :: Name -> Kind -> TyVarBndr
567 kindedTV = KindedTV
568
569 roledTV :: Name -> Role -> TyVarBndr
570 roledTV = RoledTV
571
572 kindedRoledTV :: Name -> Kind -> Role -> TyVarBndr
573 kindedRoledTV = KindedRoledTV
574
575 varK :: Name -> Kind
576 varK = VarT
577
578 conK :: Name -> Kind
579 conK = ConT
580
581 tupleK :: Int -> Kind
582 tupleK = TupleT
583
584 arrowK :: Kind
585 arrowK = ArrowT
586
587 listK :: Kind
588 listK = ListT
589
590 appK :: Kind -> Kind -> Kind
591 appK = AppT
592
593 starK :: Kind
594 starK = StarT
595
596 constraintK :: Kind
597 constraintK = ConstraintT
598
599 -------------------------------------------------------------------------------
600 -- * Role
601
602 nominal, representational, phantom :: Role
603 nominal = Nominal
604 representational = Representational
605 phantom = Phantom
606
607 -------------------------------------------------------------------------------
608 -- * Callconv
609
610 cCall, stdCall :: Callconv
611 cCall = CCall
612 stdCall = StdCall
613
614 -------------------------------------------------------------------------------
615 -- * Safety
616
617 unsafe, safe, interruptible :: Safety
618 unsafe = Unsafe
619 safe = Safe
620 interruptible = Interruptible
621
622 -------------------------------------------------------------------------------
623 -- * FunDep
624
625 funDep :: [Name] -> [Name] -> FunDep
626 funDep = FunDep
627
628 -------------------------------------------------------------------------------
629 -- * FamFlavour
630
631 typeFam, dataFam :: FamFlavour
632 typeFam = TypeFam
633 dataFam = DataFam
634
635 -------------------------------------------------------------------------------
636 -- * RuleBndr
637 ruleVar :: Name -> RuleBndrQ
638 ruleVar = return . RuleVar
639
640 typedRuleVar :: Name -> TypeQ -> RuleBndrQ
641 typedRuleVar n ty = ty >>= return . TypedRuleVar n
642
643 --------------------------------------------------------------
644 -- * Useful helper function
645
646 appsE :: [ExpQ] -> ExpQ
647 appsE [] = error "appsE []"
648 appsE [x] = x
649 appsE (x:y:zs) = appsE ( (appE x y) : zs )
650