on master help sign in
More documentation
commitd92b4a79206437d674396822d45f6e429603741d authorAndrzej Rybczak <andrzej@rybczak.net> dateMon 28 Jun 2021, 20:23 (5 years ago) parent076644f
5 files changed+66−11
src/Effectful/Internal/Env.hs+54−2 src/Effectful/State.hs+1−1 src/Effectful/State/MVar.hs+1−1 src/Effectful/Writer.hs+9−7 src/Effectful/Writer/MVar.hs+1
src/Effectful/Internal/Env.hs+54−2
@@ -40,8 +40,8 @@ import Effectful.Internal.Effect
4040
4141type role Env nominal
4242
43−-- | A thread local, mutable, strict (elements are kept in weak head normal
44−-- form), extensible record indexed by data types of kind 'Effect'.
43+-- | A strict (WHNF), thread local, mutable, extensible record indexed by types
44+-- of kind 'Effect'.
4545--
4646-- Supports forking, i.e. introduction of local branches for encapsulation of
4747-- data specific to effect interpreters.
@@ -56,6 +56,58 @@ type role Env nominal
5656--
5757-- - Modification of a specific element: /O(1)/.
5858--
59+-- Here's an example of how the environment might look:
60+--
61+-- @
62+-- e00 - e01 - e05 - e07 (*)
63+-- | | |
64+-- | e06 e08 - e09
65+-- |
66+-- e02 - e03
67+-- |
68+-- e04
69+-- @
70+--
71+-- The point of execution is currently at (*), i.e. the mainline. Moreover,
72+-- currently:
73+--
74+-- - Mainline sees @[e00, e01, e05, e07]@.
75+--
76+-- - @e01@ is an interpreted effect, its handler sees @[e00, e02, e03]@.
77+--
78+-- - @e03@ is an interpreted effect, its handler sees @[e00, e02, e04]@.
79+--
80+-- - @e05@ is an interpreted effect, its handler sees @[e00, e01, e06]@.
81+--
82+-- - @e07@ is an interpreted effect, its handler sees @[e00, e01, e05, e08,
83+-- e09]@.
84+--
85+-- If an operation from @e01@ is invoked, the environment in the middle of
86+-- handling it might look like this:
87+--
88+-- @
89+-- e00 - e01 - e05 - e07
90+-- | | |
91+-- | e06 e08 - e09
92+-- |
93+-- e02 - e03 - e10 (*)
94+-- | |
95+-- e04 e11
96+-- |
97+-- e12
98+-- @
99+--
100+-- The point of execution is at (*), i.e. inside the handler of @e01@. The
101+-- handler needed to introduce @e10@ (which introduced @e11@, which in turn
102+-- introduced @e12@), so its local environment was temporarily extended with
103+-- it. Moreover, currently:
104+--
105+-- - Handler of @e01@ sees @[e00, e02, e03, e10]@.
106+--
107+-- - Handler of @e10@ sees @[e00, e02, e03, e11]@.
108+--
109+-- - Handler of @e11@ sees @[e00, e02, e03, e12]@.
110+--
59111data Env (es :: [Effect]) = Env
60112 { _forks :: Forks
61113 , _globalRef :: IORef EnvRef
src/Effectful/State.hs+1−1
@@ -23,7 +23,7 @@ module Effectful.State
2323import Effectful.Internal.Effect
2424import Effectful.Internal.Monad
2525
26−-- | Provide access to a strict, thread local, mutable state of type @s@.
26+-- | Provide access to a strict (WHNF), thread local, mutable state of type @s@.
2727newtype State s :: Effect where
2828 State :: s -> State s m r
2929
src/Effectful/State/MVar.hs+1−1
@@ -25,7 +25,7 @@ import Control.Concurrent.MVar
2525import Effectful.Internal.Effect
2626import Effectful.Internal.Monad
2727
28−-- | Provide access to a strict, shareable, mutable state of type @s@.
28+-- | Provide access to a strict (WHNF), shareable, mutable state of type @s@.
2929newtype State s :: Effect where
3030 State :: MVar s -> State s m r
3131
src/Effectful/Writer.hs+9−7
@@ -1,4 +1,4 @@
1−-- | The 'Writer' as an effect.
1+-- | The 'Writer' effect.
22module Effectful.Writer
33 ( Writer
44 , runWriter
@@ -15,7 +15,8 @@ import Effectful.Internal.Effect
1515import Effectful.Internal.Env
1616import Effectful.Internal.Monad
1717
18−-- | Provide access to a write only value of type @w@.
18+-- | Provide access to a strict (WHNF), thread local, write only value of type
19+-- @w@.
1920newtype Writer w :: Effect where
2021 Writer :: w -> Writer w m r
2122
@@ -41,11 +42,12 @@ listen
4142 -> Eff es (a, w)
4243listen m = unsafeEff $ \es -> mask $ \restore -> do
4344 w0 <- unsafeStateEnv (\(IdE (Writer w)) -> (w, IdE (Writer mempty))) es
44− -- If an exception is thrown, restore e0 and keep parts of e1.
45− a <- restore (unEff m es) `onException`
46− unsafeModifyEnv (\(IdE (Writer w)) -> IdE (Writer (w0 <> w))) es
47− w1 <- unsafeStateEnv (\(IdE (Writer w)) -> (w, IdE (Writer (w0 <> w)))) es
48− pure (a, w1)
45+ a <- restore (unEff m es) `onException` merge es w0
46+ (a, ) <$> merge es w0
47+ where
48+ merge es w0 =
49+ -- If an exception is thrown, restore w0 and keep parts of w1.
50+ unsafeStateEnv (\(IdE (Writer w1)) -> (w1, IdE (Writer (w0 <> w1)))) es
4951
5052listens
5153 :: (Writer w :> es, Monoid w)
src/Effectful/Writer/MVar.hs+1
@@ -15,6 +15,7 @@ import Effectful.Internal.Effect
1515import Effectful.Internal.Env
1616import Effectful.Internal.Monad
1717
18+-- | Provide access to a strict (WHNF), shareable, write only value of type @w@.
1819newtype Writer w :: Effect where
1920 Writer :: MVar w -> Writer w m r
2021