1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
------------------------------------------------------------------------------ --- Library for handling global entities. --- A global entity has a name declared in the program. --- Its value can be accessed and modified by IO actions. --- Furthermore, global entities can be declared as persistent so that --- their values are stored across different program executions. --- --- Currently, it is still experimental so that its interface might --- be slightly changed in the future. --- --- A global entity `g` with an initial value `v` --- of type `t` must be declared by: --- --- g :: Global t --- g = global v spec --- --- Here, the type `t` must not contain type variables and --- `spec` specifies the storage mechanism for the --- global entity (see type `GlobalSpec`). --- --- --- @author Michael Hanus --- @version February 2017 --- @category general ------------------------------------------------------------------------------ {-# LANGUAGE CPP #-} module Global ( Global, GlobalSpec(..), global , readGlobal, safeReadGlobal, writeGlobal) where ---------------------------------------------------------------------- --- The abstract type of a global entity. data Global a = GlobalDef a GlobalSpec --- `global` is only used for the declaration of a global value --- and should not be used elsewhere. In the future, it might become a keyword. global :: a -> GlobalSpec -> Global a global v s = GlobalDef v s --- The storage mechanism for the global entity. --- @cons Temporary - the global value exists only during a single execution --- of a program --- @cons Persistent f - the global value is stored persisently in file f --- (which is created and initialized if it does not exists) data GlobalSpec = Temporary | Persistent String --- Reads the current value of a global. readGlobal :: Global a -> IO a readGlobal g = prim_readGlobal $# g prim_readGlobal :: Global a -> IO a prim_readGlobal external --- Safely reads the current value of a global. --- If `readGlobal` fails (e.g., due to a corrupted persistent storage), --- the global is re-initialized with the default value given as --- the second argument. safeReadGlobal :: Global a -> a -> IO a safeReadGlobal g dflt = catch (readGlobal g) (\_ -> writeGlobal g dflt >> return dflt) --- Updates the value of a global. --- The value is evaluated to a ground constructor term before it is updated. writeGlobal :: Global a -> a -> IO () writeGlobal g v = (prim_writeGlobal $# g) $## v prim_writeGlobal :: Global a -> a -> IO () prim_writeGlobal external ------------------------------------------------------------------------ |