on master help sign in
Allow adding new effects in Eff programs

This is only allowed if there is a handler for all computation contexts the program could run in. In particular, if the program is in 'Eff' rather than 'EffT', then it is only valid for 'pure' handlers, like State. Note that, as a result, the effects a program can run isn't now limited to the top level set of effects. In the case of 'pure' effects, such as State or Rnd, I argue that this is okay. In the case of external effects such as IO related effects, you can only add effects if the top level context is impure. Again, I argue that this is okay - if you don't want to add impure effects, keep the top level context generic. Also added a test (by way of example) in effects004

commit7f9fba59b598129d88d3e7ef1ab9b4a6a08d6a23 authorEdwin Brady <ecb10@st-andrews.ac.uk> dateSun 5 Apr 2015, 20:25 (12 years ago) parentf9c3fd9
2 files changed+11
idris.cabal+4 libs/effects/Effects.idr+7
idris.cabal+4
@@ -373,6 +373,10 @@ Extra-source-files:
373373 test/effects003/*.idr
374374 test/effects003/expected
375375 test/effects003/input
376+ test/effects004/run
377+ test/effects004/*.idr
378+ test/effects004/expected
379+ test/effects004/input
376380
377381 test/error001/run
378382 test/error001/*.idr
libs/effects/Effects.idr+7
@@ -168,6 +168,11 @@ data EffM : (m : Type -> Type) -> (x : Type)
168168 liftP : (prf : SubList ys xs) ->
169169 EffM m t ys ys' -> EffM m t xs (\v => updateWith (ys' v) xs prf)
170170
171+ new : Handler e' m => (e : EFFECT) -> resTy ->
172+ {auto prf : e = MkEff resTy e'} ->
173+ EffM m t (e :: es) (\v => e :: es) ->
174+ EffM m t es (\v => es)
175+
171176 (:-) : (l : ty) ->
172177 EffM m t [x] xs' -> -- [x] (\v => xs) ->
173178 EffM m t [l ::: x] (\v => map (l :::) (xs' v))
@@ -263,6 +268,8 @@ eff env (callP prf effP) k = execEff env prf effP k
263268eff env (liftP prf effP) k
264269 = let env' = dropEnv env prf in
265270 eff env' effP (\p', envk => k p' (rebuildEnv envk prf env))
271+eff env (new (MkEff resTy newEff) res {prf=Refl} effP) k
272+ = eff (res :: env) effP (\p', (val :: envk) => k p' envk)
266273-- FIXME:
267274-- xs is needed explicitly because otherwise the pattern binding for
268275-- 'l' appears too late. Solution seems to be to reorder patterns at the