Skip to content

Why do mutable State interpreters not require embedded IO? #301

@Burtannia

Description

@Burtannia

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions