on master help sign in
Some Eff experimentation, adding a 'test' command

For allowing effects which might fail, and testing results. Still no nice syntactic sugar for it though.

commit1bc3002015fdb34d3a8bca9d33e1b41e04baea69 authorEdwin Brady <ecb10@st-andrews.ac.uk> dateSun 13 Oct 2013, 15:22 (13 years ago) parentdb96d75
6 files changed+97−4
effects/Effects.idr+63−1 src/Idris/AbsSyntax.hs+7 src/Idris/AbsSyntaxTree.hs+11−3 src/Idris/DSL.hs+3 src/Idris/ElabTerm.hs+1 src/Idris/ParseExpr.hs+12
effects/Effects.idr+63−1
@@ -79,7 +79,12 @@ findSubList (S n) ctxt goal
7979updateResTy : (xs : List EFFECT) -> EffElem e a xs -> e a b t ->
8080 List EFFECT
8181updateResTy {b} (MkEff a e :: xs) Here n = (MkEff b e) :: xs
82−updateResTy (x :: xs) (There p) n = x :: updateResTy xs p n
82+updateResTy (x :: xs) (There p) n = x :: updateResTy xs p n
83+
84+updateResTyImm : (xs : List EFFECT) -> EffElem e a xs -> Type ->
85+ List EFFECT
86+updateResTyImm (MkEff a e :: xs) Here b = (MkEff b e) :: xs
87+updateResTyImm (x :: xs) (There p) b = x :: updateResTyImm xs p b
8388
8489infix 5 :::, :-, :=
8590
@@ -111,6 +116,15 @@ data EffM : (m : Type -> Type) ->
111116 new : Handler e m =>
112117 res -> EffM m (MkEff res e :: xs) (MkEff res' e :: xs') a ->
113118 EffM m xs xs' a
119+ test : (prf : EffElem e (Either l r) xs) ->
120+ EffM m (updateResTyImm xs prf l) xs' t ->
121+ EffM m (updateResTyImm xs prf r) xs' t ->
122+ EffM m xs xs' t
123+ test_lbl : {x : lbl} ->
124+ (prf : EffElem e (LRes x (Either l r)) xs) ->
125+ EffM m (updateResTyImm xs prf (LRes x l)) xs' t ->
126+ EffM m (updateResTyImm xs prf (LRes x r)) xs' t ->
127+ EffM m xs xs' t
114128 catch : Catchable m err =>
115129 EffM m xs xs' a -> (err -> EffM m xs xs' a) ->
116130 EffM m xs xs' a
@@ -132,6 +146,27 @@ effect' : {a, b: _} -> {e : Effect} ->
132146 EffM m xs (updateResTy xs prf eff) t
133147effect' {prf} e = effect prf e
134148
149+data WrapEffM : (m : Type -> Type) ->
150+ List EFFECT -> List EFFECT -> Type -> Type where
151+ WEffM : EffM m xs xs' t -> WrapEffM m xs xs' t
152+
153+-- wrap subprograms to prevent lifting (need to guarantee same effects as
154+-- parent!)
155+
156+test_lbl' : {x : lbl} ->
157+ {default tactics { applyTactic findEffElem 20; solve; }
158+ prf : EffElem e (LRes x (Either l r)) xs} ->
159+ WrapEffM m (updateResTyImm xs prf (LRes x l)) xs' t ->
160+ WrapEffM m (updateResTyImm xs prf (LRes x r)) xs' t ->
161+ EffM m xs xs' t
162+test_lbl' {prf} (WEffM l) (WEffM r) = test_lbl prf l r
163+
164+test' : {default tactics { applyTactic findEffElem 20; solve; }
165+ prf : EffElem e (Either l r) xs} ->
166+ EffM m (updateResTyImm xs prf l) xs' t ->
167+ EffM m (updateResTyImm xs prf r) xs' t ->
168+ EffM m xs xs' t
169+test' {prf} l r = test prf l r
135170
136171-- for 'do' notation
137172
@@ -164,6 +199,29 @@ execEff (val :: env) Here eff' k
164199execEff (val :: env) (There p) eff k
165200 = execEff env p eff (\env', v => k (val :: env') v)
166201
202+private
203+testEff : Env m xs -> (p : EffElem e (Either l r) xs) ->
204+ (Env m (updateResTyImm xs p l) -> m b) ->
205+ (Env m (updateResTyImm xs p r) -> m b) ->
206+ m b
207+testEff (Left err :: env) Here lk rk = lk (err :: env)
208+testEff (Right ok :: env) Here lk rk = rk (ok :: env)
209+testEff (val :: env) (There p) lk rk
210+ = testEff env p (\envk => lk (val :: envk))
211+ (\envk => rk (val :: envk))
212+
213+private
214+testEffLbl : {x : lbl} ->
215+ Env m xs -> (p : EffElem e (LRes x (Either l r)) xs) ->
216+ (Env m (updateResTyImm xs p (LRes x l)) -> m b) ->
217+ (Env m (updateResTyImm xs p (LRes x r)) -> m b) ->
218+ m b
219+testEffLbl ((lbl := Left err) :: env) Here lk rk = lk ((lbl := err) :: env)
220+testEffLbl ((lbl := Right ok) :: env) Here lk rk = rk ((lbl := ok) :: env)
221+testEffLbl (val :: env) (There p) lk rk
222+ = testEffLbl env p (\envk => lk (val :: envk))
223+ (\envk => rk (val :: envk))
224+
167225-- Q: Instead of m b, implement as StateT (Env m xs') m b, so that state
168226-- updates can be propagated even through failing computations?
169227
@@ -178,6 +236,10 @@ eff env (lift prf effP) k
178236eff env (new r prog) k
179237 = let env' = r :: env in
180238 eff env' prog (\(v :: envk), p' => k envk p')
239+eff env (test prf l r) k
240+ = testEff env prf (\envk => eff envk l k) (\envk => eff envk r k)
241+eff env (test_lbl prf l r) k
242+ = testEffLbl env prf (\envk => eff envk l k) (\envk => eff envk r k)
181243eff env (catch prog handler) k
182244 = catch (eff env prog k)
183245 (\e => eff env (handler e) k)
src/Idris/AbsSyntax.hs+7
@@ -684,6 +684,7 @@ expandParams dec ps ns infs tm = en tm
684684 en (PAlternative a as) = PAlternative a (map en as)
685685 en (PHidden t) = PHidden (en t)
686686 en (PUnifyLog t) = PUnifyLog (en t)
687+ en (PNoImplicits t) = PNoImplicits (en t)
687688 en (PDoBlock ds) = PDoBlock (map (fmap en) ds)
688689 en (PProof ts) = PProof (map (fmap en) ts)
689690 en (PTactics ts) = PTactics (map (fmap en) ts)
@@ -1011,6 +1012,7 @@ implicitise syn ignore ist tm = -- trace ("INCOMING " ++ showImp True tm) $
10111012 imps False (n:env) sc
10121013 imps top env (PHidden tm) = imps False env tm
10131014 imps top env (PUnifyLog tm) = imps False env tm
1015+ imps top env (PNoImplicits tm) = imps False env tm
10141016 imps top env _ = return ()
10151017
10161018 pibind using [] sc = sc
@@ -1100,6 +1102,7 @@ addImpl' inpat env infns ist ptm = ai (zip env (repeat Nothing)) ptm
11001102 ai env (PTactics ts) = PTactics (map (fmap (ai env)) ts)
11011103 ai env (PRefl fc tm) = PRefl fc (ai env tm)
11021104 ai env (PUnifyLog tm) = PUnifyLog (ai env tm)
1105+ ai env (PNoImplicits tm) = PNoImplicits (ai env tm)
11031106 ai env tm = tm
11041107
11051108 handleErr (Left err) = PElabError err
@@ -1364,6 +1367,8 @@ matchClause' names i x y = checkRpts $ match (fullApp x) (fullApp y) where
13641367 match (PHidden x) (PHidden y) = match' x y
13651368 match (PUnifyLog x) y = match' x y
13661369 match x (PUnifyLog y) = match' x y
1370+ match (PNoImplicits x) y = match' x y
1371+ match x (PNoImplicits y) = match' x y
13671372 match Placeholder _ = return []
13681373 match _ Placeholder = return []
13691374 match (PResolveTC _) _ = return []
@@ -1411,6 +1416,7 @@ substMatchShadow n shs tm t = sm shs t where
14111416 sm xs (PAlternative a as) = PAlternative a (map (sm xs) as)
14121417 sm xs (PHidden x) = PHidden (sm xs x)
14131418 sm xs (PUnifyLog x) = PUnifyLog (sm xs x)
1419+ sm xs (PNoImplicits x) = PNoImplicits (sm xs x)
14141420 sm xs x = x
14151421
14161422 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
@@ -1431,6 +1437,7 @@ shadow n n' t = sm t where
14311437 sm (PAlternative a as) = PAlternative a (map sm as)
14321438 sm (PHidden x) = PHidden (sm x)
14331439 sm (PUnifyLog x) = PUnifyLog (sm x)
1440+ sm (PNoImplicits x) = PNoImplicits (sm x)
14341441 sm x = x
14351442
14361443
src/Idris/AbsSyntaxTree.hs+11−3
@@ -558,6 +558,7 @@ data PTerm = PQuote Raw
558558 | PImpossible -- ^ Special case for declaring when an LHS can't typecheck
559559 | PCoerced PTerm -- ^ To mark a coerced argument, so as not to coerce twice
560560 | PUnifyLog PTerm -- ^ dump a trace of unifications when building term
561+ | PNoImplicits PTerm -- ^ never run implicit converions on the term
561562 deriving Eq
562563{-!
563564deriving instance Binary PTerm
@@ -582,6 +583,7 @@ mapPT f t = f (mpt t) where
582583 mpt (PProof ts) = PProof (map (fmap (mapPT f)) ts)
583584 mpt (PTactics ts) = PTactics (map (fmap (mapPT f)) ts)
584585 mpt (PUnifyLog tm) = PUnifyLog (mapPT f tm)
586+ mpt (PNoImplicits tm) = PNoImplicits (mapPT f tm)
585587 mpt (PGoal fc r n sc) = PGoal fc (mapPT f r) n (mapPT f sc)
586588 mpt x = x
587589
@@ -682,9 +684,9 @@ instance Sized a => Sized (PArg' a) where
682684deriving instance Binary PArg'
683685!-}
684686
685−pimp n t = PImp 0 True n t ""
686−pexp t = PExp 0 False t ""
687−pconst t = PConstraint 0 False t ""
687+pimp n t = PImp 1 True n t ""
688+pexp t = PExp 1 False t ""
689+pconst t = PConstraint 1 False t ""
688690ptacimp n s t = PTacImplicit 0 True n s t ""
689691
690692type PArg = PArg' PTerm
@@ -1178,6 +1180,7 @@ showImp ist impl colour tm = se 10 [] tm where
11781180 se p bnd (PElabError s) = show s
11791181 se p bnd (PCoerced t) = se p bnd t
11801182 se p bnd (PUnifyLog t) = "%unifyLog " ++ se p bnd t
1183+ se p bnd (PNoImplicits t) = "%noimplicit " ++ se p bnd t
11811184-- se p bnd x = "Not implemented"
11821185
11831186 slist' p bnd (PApp _ (PRef _ nil) _)
@@ -1245,6 +1248,7 @@ instance Sized PTerm where
12451248 size (PAlternative a alts) = 1 + size alts
12461249 size (PHidden hidden) = size hidden
12471250 size (PUnifyLog tm) = size tm
1251+ size (PNoImplicits tm) = size tm
12481252 size PType = 1
12491253 size (PConstant const) = 1 + size const
12501254 size Placeholder = 1
@@ -1280,6 +1284,7 @@ allNamesIn tm = nub $ ni [] tm
12801284 ni env (PDPair _ l t r) = ni env l ++ ni env t ++ ni env r
12811285 ni env (PAlternative a ls) = concatMap (ni env) ls
12821286 ni env (PUnifyLog tm) = ni env tm
1287+ ni env (PNoImplicits tm) = ni env tm
12831288 ni env _ = []
12841289
12851290-- Return names which are free in the given term.
@@ -1305,6 +1310,7 @@ namesIn uvars ist tm = nub $ ni [] tm
13051310 ni env (PAlternative a as) = concatMap (ni env) as
13061311 ni env (PHidden tm) = ni env tm
13071312 ni env (PUnifyLog tm) = ni env tm
1313+ ni env (PNoImplicits tm) = ni env tm
13081314 ni env _ = []
13091315
13101316-- Return which of the given names are used in the given term.
@@ -1330,4 +1336,6 @@ usedNamesIn vars ist tm = nub $ ni [] tm
13301336 ni env (PAlternative a as) = concatMap (ni env) as
13311337 ni env (PHidden tm) = ni env tm
13321338 ni env (PUnifyLog tm) = ni env tm
1339+ ni env (PNoImplicits tm) = ni env tm
13331340 ni env _ = []
1341+
src/Idris/DSL.hs+3
@@ -37,6 +37,8 @@ expandDo dsl (PDPair fc l t r) = PDPair fc (expandDo dsl l) (expandDo dsl t)
3737 (expandDo dsl r)
3838expandDo dsl (PAlternative a as) = PAlternative a (map (expandDo dsl) as)
3939expandDo dsl (PHidden t) = PHidden (expandDo dsl t)
40+expandDo dsl (PNoImplicits t) = PNoImplicits (expandDo dsl t)
41+expandDo dsl (PUnifyLog t) = PUnifyLog (expandDo dsl t)
4042expandDo dsl (PReturn fc) = dsl_return dsl
4143expandDo dsl (PRewrite fc r t ty)
4244 = PRewrite fc r (expandDo dsl t) ty
@@ -90,6 +92,7 @@ var dsl n t i = v' i t where
9092 v' i (PHidden t) = PHidden (v' i t)
9193 v' i (PIdiom f t) = PIdiom f (v' i t)
9294 v' i (PDoBlock ds) = PDoBlock (map (fmap (v' i)) ds)
95+ v' i (PNoImplicits t) = PNoImplicits (v' i t)
9396 v' i t = t
9497
9598 mkVar fc 0 = case index_first dsl of
src/Idris/ElabTerm.hs+1
@@ -142,6 +142,7 @@ elab ist info pattern tcgen fn tm
142142 local f = do e <- get_env
143143 return (f `elem` map fst e)
144144
145+ elab' ina (PNoImplicits t) = elab' ina t -- skip elabE step
145146 elab' ina PType = do apply RType []; solve
146147 elab' ina (PConstant c) = do apply (RConstant c) []; solve
147148 elab' ina (PQuote r) = do fill r; solve
src/Idris/ParseExpr.hs+12
@@ -177,6 +177,7 @@ internalExpr syn =
177177 try (app syn)
178178 <|> try (matchApp syn)
179179 <|> try (unifyLog syn)
180+ <|> try (noImplicits syn)
180181 <|> recordType syn
181182 <|> try (simpleExpr syn)
182183 <|> lambda syn
@@ -441,6 +442,17 @@ unifyLog syn = do lchar '%'; reserved "unifyLog";
441442 return (PUnifyLog tm)
442443 <?> "unification log expression"
443444
445+{- | Parses a no implicits expression
446+NoImplicits ::=
447+ '%' 'noImplicits' SimpleExpr
448+ ;
449+-}
450+noImplicits :: SyntaxInfo -> IdrisParser PTerm
451+noImplicits syn = do lchar '%'; reserved "noImplicits";
452+ tm <- simpleExpr syn
453+ return (PNoImplicits tm)
454+ <?> "no implicits expression"
455+
444456{- | Parses a function application expression
445457App ::=
446458 'mkForeign' Arg Arg*