Effect.State.Static.Shared makes use of an MVar. This is allocated using unsafeEff_ meaning that we can eventually run our program using runPureEff. This makes me quite uncomfortable.
action :: (State Bool :> es, Error () :> es) => Eff es Bool
action = do
(put True *> throwError ()) `catchError` \_ () -> pure ()
get
main :: IO ()
main = print $ runPureEff (evalStateShared False $ runError @() action)
A much more rational approach, in my opinion, would be to have the interpreter enforce that IOE be part of the effect stack and then we can run our program with runEff. As an example, I would expect something akin to Polysemy's interpreters:
runAtomicStateTVar :: Member (Embed IO) r => TVar s -> Sem (AtomicState s ': r) a -> Sem r a
Could somebody explain the rational behind using unsafe actions here and how we can be sure they're safe?
Effect.State.Static.Sharedmakes use of anMVar. This is allocated usingunsafeEff_meaning that we can eventually run our program usingrunPureEff. This makes me quite uncomfortable.A much more rational approach, in my opinion, would be to have the interpreter enforce that
IOEbe part of the effect stack and then we can run our program withrunEff. As an example, I would expect something akin to Polysemy's interpreters:runAtomicStateTVar :: Member (Embed IO) r => TVar s -> Sem (AtomicState s ': r) a -> Sem r aCould somebody explain the rational behind using unsafe actions here and how we can be sure they're safe?