@@ -264,4 +264,66 @@ module Math where
264264 }
265265
266266 foreign import math :: Math
267+
268+module Eff where
269+
270+ foreign import data Eff :: # ! -> * -> *
271+
272+ foreign import retEff "function retEff(a) { return function() { return a; }; }" :: forall e a. a -> Eff e a
273+
274+ foreign import bindEff "function bindEff(a) { return function(f) { return function() { return f(a())(); }; }; }" :: forall e a b. Eff e a -> (a -> Eff e b) -> Eff e b
275+
276+ type Pure a = forall e. Eff e a
277+
278+ foreign import runPure :: forall a. Pure a -> a
279+
280+ eff = { ret: retEff, bind: bindEff }
281+
282+module Errors where
283+
284+ import Eff
285+
286+ foreign import data Error :: * -> !
287+
288+ foreign import throwError "function throwError(e) { return function() { throw e; }; }" :: forall e r. e -> Eff (err :: Error e | r) {}
289+
290+ foreign import catchError "function catchError(c) { return function(t) { return function() { try { return t(); } catch(e) { return c(e)(); } }; }; }" :: forall e r a. (e -> Eff r a) -> Eff (err :: Error e | r) a -> Eff r a
291+
292+module IORef where
293+
294+ import Eff
295+
296+ foreign import data Ref :: !
297+
298+ foreign import data IORef :: * -> *
299+
300+ foreign import newIORef :: forall s r. a -> Eff (ref :: Ref | r) (IORef s)
301+
302+ foreign import readIORef :: forall s r. IORef s -> Eff (ref :: Ref | r) s
303+
304+ foreign import writeIORef :: forall s r. IORef s -> s -> Eff (ref :: Ref | r) {}
305+
306+module Trace where
307+
308+ import Eff
309+
310+ foreign import data Trace :: !
311+
312+ foreign import trace "function trace(s) { return function() { console.log(s); return {}; }; }" :: forall r. String -> Eff (trace :: Trace | r) {}
313+
314+module ST where
315+
316+ import Eff
317+
318+ foreign import data ST :: * -> !
319+
320+ foreign import data STRef :: * -> * -> *
321+
322+ foreign import newSTRef :: forall a h r. a -> Eff (st :: ST h | r) (STRef h a)
323+
324+ foreign import readSTRef :: forall a h r. STRef h a -> Eff (st :: ST h | r) a
325+
326+ foreign import modifySTRef :: forall a h r. (a -> a) -> STRef h a -> Eff (st :: ST h | r) {}
327+
328+ foreign import runST :: forall a r. (forall h. Eff (st :: ST h | r) a) -> Eff r a
267329