Idris2/libs/base/Data/IORef.idr
Edwin Brady dbdf7dab3d Back to HasIO, remove MonadIO
Following a fairly detailed discussion on slack, the feeling is
generally that it's better to have a single interface. While precision
is nice, it doesn't appear to buy us anything here. If that turns out to
be wrong, or limiting somehow, we can revisit it later. Also:

- it's easier for backend authors if the type of IO operations is
  slightly less restrictive. For example, if it's in HasIO, that limits
  alternative implementations, which might be awkward for some
  alternative back ends.
- it's one less extra detail to learn. This is minor, but there needs to
  be a clear advantage if there's more detail to learn.
- It is difficult to think of an underlying type that can't have a Monad
  instance (I have personally never encountered one - if they turns out
  to exist, again, we can revisit!)
2020-06-21 19:21:22 +01:00

37 lines
943 B
Idris

module Data.IORef
-- Implemented externally
-- e.g., in Scheme, passed around as a box
data Mut : Type -> Type where [external]
%extern prim__newIORef : forall a . a -> (1 x : %World) -> IORes (Mut a)
%extern prim__readIORef : forall a . Mut a -> (1 x : %World) -> IORes a
%extern prim__writeIORef : forall a . Mut a -> (1 val : a) -> (1 x : %World) -> IORes ()
export
data IORef : Type -> Type where
MkRef : Mut a -> IORef a
export
newIORef : HasIO io => a -> io (IORef a)
newIORef val
= do m <- primIO (prim__newIORef val)
pure (MkRef m)
%inline
export
readIORef : HasIO io => IORef a -> io a
readIORef (MkRef m) = primIO (prim__readIORef m)
%inline
export
writeIORef : HasIO io => IORef a -> (1 val : a) -> io ()
writeIORef (MkRef m) val = primIO (prim__writeIORef m val)
export
modifyIORef : HasIO io => IORef a -> (a -> a) -> io ()
modifyIORef ref f
= do val <- readIORef ref
writeIORef ref (f val)