on fbc5b30 help sign in
effectful/bench/Countdown.hs
276 lines 7.0 kB history raw
1{-# LANGUAGE CPP #-}
2module Countdown where
4import Data.Functor.Identity
6-- eff
7#ifdef VERSION_eff
8import qualified Control.Effect as L
9#endif
11-- effectful
12import qualified Effectful.Monad as E
13import qualified Effectful.Reader as E
14import qualified Effectful.State as E
15import qualified Effectful.State.Dynamic as DE
16import qualified Effectful.State.MVar as ME
18-- freer-simple
19#ifdef VERSION_freer_simple
20import qualified Control.Monad.Freer as FS
21import qualified Control.Monad.Freer.Reader as FS
22import qualified Control.Monad.Freer.State as FS
23#endif
25-- fused-effects
26#ifdef VERSION_fused_effects
27import qualified Control.Algebra as FE
28import qualified Control.Carrier.Reader as FE
29import qualified Control.Carrier.State.Strict as FE
30#endif
32-- mtl
33import qualified Control.Monad.Reader as M
34import qualified Control.Monad.State as M
36-- polysemy
37#ifdef VERSION_polysemy
38import qualified Polysemy as P
39import qualified Polysemy.Reader as P
40import qualified Polysemy.State as P
41#endif
43----------------------------------------
44-- reference
46countdownRef :: Integer -> (Integer, Integer)
47countdownRef n = if n <= 0 then (n, n) else countdownRef $ n - 1
48{-# NOINLINE countdownRef #-}
50----------------------------------------
51-- mtl
53programMtl :: M.MonadState Integer m => m Integer
54programMtl = do
55 n <- M.get @Integer
56 if n <= 0
57 then pure n
58 else do
59 M.put (n - 1)
60 programMtl
61{-# NOINLINE programMtl #-}
63countdownMtl :: Integer -> (Integer, Integer)
64countdownMtl n = flip M.runState n $ programMtl
66countdownMtlDeep :: Integer -> (Integer, Integer)
67countdownMtlDeep n = runIdentity
68 . runR . runR . runR . runR . runR
69 . flip M.runStateT n
70 . runR . runR . runR . runR . runR
71 $ programMtl
72 where
73 runR = flip M.runReaderT ()
75----------------------------------------
76-- effectful (pure)
78programEffectfulStatic :: E.State Integer E.:> es => E.Eff es Integer
79programEffectfulStatic = do
80 n <- E.get @Integer
81 if n <= 0
82 then pure n
83 else do
84 E.put (n - 1)
85 programEffectfulStatic
86{-# NOINLINE programEffectfulStatic #-}
88countdownEffectfulStatic :: Integer -> (Integer, Integer)
89countdownEffectfulStatic n = E.runEff . E.runState n $ programEffectfulStatic
91countdownEffectfulStaticDeep :: Integer -> (Integer, Integer)
92countdownEffectfulStaticDeep n = E.runEff
93 . runR . runR . runR . runR . runR
94 . E.runState n
95 . runR . runR . runR . runR . runR
96 $ programEffectfulStatic
97 where
98 runR = E.runReader ()
100----------------------------------------
101-- effectful (mvar)
103programEffectfulMVar :: ME.State Integer E.:> es => E.Eff es Integer
104programEffectfulMVar = do
105 n <- ME.get @Integer
106 if n <= 0
107 then pure n
108 else do
109 ME.put (n - 1)
110 programEffectfulMVar
111{-# NOINLINE programEffectfulMVar #-}
113countdownEffectfulMVar :: Integer -> (Integer, Integer)
114countdownEffectfulMVar n = E.runEff . ME.runState n $ programEffectfulMVar
116countdownEffectfulMVarDeep :: Integer -> (Integer, Integer)
117countdownEffectfulMVarDeep n = E.runEff
118 . runR . runR . runR . runR . runR
119 . ME.runState n
120 . runR . runR . runR . runR . runR
121 $ programEffectfulMVar
122 where
123 runR = E.runReader ()
125----------------------------------------
126-- effectful (dynamic)
128programEffectfulDynamic :: DE.State Integer E.:> es => E.Eff es Integer
129programEffectfulDynamic = do
130 n <- DE.get @Integer
131 if n <= 0
132 then pure n
133 else do
134 DE.put (n - 1)
135 programEffectfulDynamic
136{-# NOINLINE programEffectfulDynamic #-}
138countdownEffectfulDynPure :: Integer -> (Integer, Integer)
139countdownEffectfulDynPure n = E.runEff . DE.runState n $ programEffectfulDynamic
141countdownEffectfulDynMVar :: Integer -> (Integer, Integer)
142countdownEffectfulDynMVar n = E.runEff . DE.runStateMVar n $ programEffectfulDynamic
144countdownEffectfulDynPureDeep :: Integer -> (Integer, Integer)
145countdownEffectfulDynPureDeep n = E.runEff
146 . runR . runR . runR . runR . runR
147 . DE.runState n
148 . runR . runR . runR . runR . runR
149 $ programEffectfulDynamic
150 where
151 runR = E.runReader ()
153countdownEffectfulDynMVarDeep :: Integer -> (Integer, Integer)
154countdownEffectfulDynMVarDeep n = E.runEff
155 . runR . runR . runR . runR . runR
156 . DE.runStateMVar n
157 . runR . runR . runR . runR . runR
158 $ programEffectfulDynamic
159 where
160 runR = E.runReader ()
162----------------------------------------
163-- fused-effects
165#ifdef VERSION_fused_effects
167programFusedEffects :: FE.Has (FE.State Integer) sig m => m Integer
168programFusedEffects = do
169 n <- FE.get @Integer
170 if n <= 0
171 then pure n
172 else do
173 FE.put (n - 1)
174 programFusedEffects
175{-# NOINLINE programFusedEffects #-}
177countdownFusedEffects :: Integer -> (Integer, Integer)
178countdownFusedEffects n = FE.run . FE.runState n $ programFusedEffects
180countdownFusedEffectsDeep :: Integer -> (Integer, Integer)
181countdownFusedEffectsDeep n = FE.run
182 . runR . runR . runR . runR . runR
183 . FE.runState n
184 . runR . runR . runR . runR . runR
185 $ programFusedEffects
186 where
187 runR = FE.runReader ()
189#endif
191----------------------------------------
192-- polysemy
194#ifdef VERSION_polysemy
196programPolysemy :: P.Member (P.State Integer) r => P.Sem r Integer
197programPolysemy = do
198 n <- P.get @Integer
199 if n <= 0
200 then pure n
201 else do
202 P.put (n - 1)
203 programPolysemy
204{-# NOINLINE programPolysemy #-}
206countdownPolysemy :: Integer -> (Integer, Integer)
207countdownPolysemy n = P.run . P.runState n $ programPolysemy
209countdownPolysemyDeep :: Integer -> (Integer, Integer)
210countdownPolysemyDeep n = P.run
211 . runR . runR . runR . runR . runR
212 . P.runState n
213 . runR . runR . runR . runR . runR
214 $ programPolysemy
215 where
216 runR = P.runReader ()
218#endif
220----------------------------------------
221-- eff
223#ifdef VERSION_eff
225programEff :: L.State Integer L.:< es => L.Eff es Integer
226programEff = do
227 n <- L.get @Integer
228 if n <= 0
229 then pure n
230 else do
231 L.put (n - 1)
232 programEff
233{-# NOINLINE programEff #-}
235countdownEff :: Integer -> (Integer, Integer)
236countdownEff n = L.run . L.runState n $ programEff
238countdownEffDeep :: Integer -> (Integer, Integer)
239countdownEffDeep n = L.run
240 . runR . runR . runR . runR . runR
241 . L.runState n
242 . runR . runR . runR . runR . runR
243 $ programEff
244 where
245 runR = L.runReader ()
247#endif
249----------------------------------------
250-- freer-simple
252#ifdef VERSION_freer_simple
254programFreerSimple :: FS.Member (FS.State Integer) es => FS.Eff es Integer
255programFreerSimple = do
256 n <- FS.get @Integer
257 if n <= 0
258 then pure n
259 else do
260 FS.put (n - 1)
261 programFreerSimple
262{-# NOINLINE programFreerSimple #-}
264countdownFreerSimple :: Integer -> (Integer, Integer)
265countdownFreerSimple n = FS.run . FS.runState n $ programFreerSimple
267countdownFreerSimpleDeep :: Integer -> (Integer, Integer)
268countdownFreerSimpleDeep n = FS.run
269 . runR . runR . runR . runR . runR
270 . FS.runState n
271 . runR . runR . runR . runR . runR
272 $ programFreerSimple
273 where
274 runR = FS.runReader ()
276#endif