In handling higher-order effects, it's easy to work with **multi-shot delimited continuations**.
This enables an almost complete emulation of "Algebraic Effects and Handlers".
For more details, please refer to
the [example code](heftia-effects/Example/Continuation/Main.hs).
### Two interpretations of the `censor` effect for Writer
Let's consider the following Writer effectful program:
```hs
hello :: (Tell String <:m,Monadm)=> m ()
hello = do
tell "Hello"
tell " world!"
censorHello :: (Tell String <:m,WriterHString<<:m,Monadm)=> m ()
censorHello =
censor
( \s ->
if s == "Hello" then
"Goodbye"
else if s == "Hello world!" then
"Hello world!!"
else
s
)
hello
```
For `censorHello`, should the final written string be `"Goodbye world!"` (Pre-applying behavior) ?
Or should it be `"Hello world!!"` (Post-applying behavior) ?
With Heftia, **you can freely choose either behavior depending on which higher-order effect interpreter (which we call an elaborator) you use**.
```hs
main :: IO ()
main = runEff do
(sPre, _) <-
interpretTell
. interpretH (elaborateWriterPre @String)
$ censorHello
(sPost, _) <-
interpretTell
. interpretH (elaborateWriterPost @String)
$ censorHello
liftIO $ putStrLn $ "Pre-applying: " <> sPre
liftIO $ putStrLn $ "Post-applying: " <> sPost
```
Using the `elaborateWriterPre` elaborator, you'll get "Goodbye world!", whereas with the `elaborateWriterPost` elaborator, you'll get "Hello world!!".
```
Pre-applying: Goodbye world!
Post-applying: Hello world!!
```
For more details, please refer to the [complete code](https://github.com/sayo-hs/heftia/blob/develop/heftia-effects/Example/Writer/Main.hs) and the [implementation of the elaborator](https://github.com/sayo-hs/heftia/blob/develop/heftia-effects/src/Control/Effect/Handler/Heftia/Writer.hs).
~~Examples with explanations can be found in the [docs/examples/](https://github.com/sayo-hs/heftia/tree/master/docs/examples) directory.~~ Documents have become outdated.
### The *reset* behavior of the scopes held by unhandled higher-order effects
When attempting to interpret an effect while there are unhandled higher-order effects present, you cannot obtain delimited continuations beyond the action scope held by these unhandled higher-order effects.
It appears as if a *reset* (in the sense of *shift/reset*) is applied to each of the scopes still held by the remaining unhandled higher-order effects.
In other words, to obtain delimited continuations that span across scopes or to maintain state across scopes,
it is necessary to first handle and eliminate all higher-order effects that hold those scopes,
and then handle the effect targeted for stateful interpretation in that order.
For this, it may be necessary to perform *multi-layering* as needed. For an example of multi-layering,
see [Example/Continuation2](https://github.com/sayo-hs/heftia/blob/f4989e92c31ae2632762afcff306ffa48c307c56/heftia-effects/Example/Continuation2/Main.hs).
For more details, please refer to the documentation of the `interpretRec` family of functions.