Polysemy: Interpretation and effects injection
As seen previously we can have interpreters which relies on other interpreters.
While you could simply add the required effects to the list, you may want to hide it (eg. to have dynamique interpreters).
In order to do it, you have many raise*
functions.
Let's have a look at View
:
data View v m a where
See :: View v m v
View
gives a way to cache expensive computations dynamically.
Let's imagine a simple app:
app = do
name0 <- see
embed $ putStrLn $ "Your name is " <> name0
name1 <- see
embed $ putStrLn $ "Hello " <> name1
we can leverage raiseUnder
which injects an effect as follows:
intrApp =
runM
. evalState ()
. viewToState (\() -> embed $ putStrLn "What's your name?" >> getLine)
. raiseUnder @(State ())
Here raiseUnder
will change effects to '[View String, State (), Embed IO]
See how it runs:
What's your name?
Gautier
Your name is Gautier
Hello Gautier
Note: actually viewToState
is more general and invalidate the cache once the state changes
See the full the code here.