This repository was archived by the owner on Oct 4, 2020. It is now read-only.
  
  
  
  
  
Description
If representation of Eff in JS runtime, was free monad-ish way, like this:
Eff a 
 = { tag: "effect", val0 :: Void,  val1 :: Unit -> a } 
 | { tag: "pure",   val0 :: Void,  val1 :: a } 
 | { tag: "map",    val0 :: Eff b, val1 :: b -> a } 
 | { tag: "apply",  val0 :: Eff a, val1 :: Eff (b -> a) } 
 | { tag: "bind",   val0 :: Eff b, val1 :: b -> Eff a } then:
exports.pureE = function (a) {
  return { tag: "pure", val0: null, val1: a }
};
exports.bindE = function (a) {
  return function (f) {
    return { tag: "bind", val0: a, val1: f }
  };
};
exports.applyE = function (f) {
  return function (a) {
    return { tag: "apply", val0: a, val1: f }
  };
};
exports.unsafeRun = function (eff) {
  // TODO: fold eff in a stack safe way.
};
exports.runPure = function (eff) {
  return unsafeRun(eff)
};This will make bind stack safe by default (no need for MonadRec)
Disadvantages:
- now, one could just grab any Eff value from JS and call it, as it's represented as a function. After proposed change, one would need to require Control/Monad/Eff.js first to get reference tounsafeRunand then use it to run the Eff.
- significantly complex than what we have now (not as complex as Aff's implementation as Eff is sync)
- braking change
- as there will be less functions, might be harder to debug
Advantages:
- instead of allocate new functions on common operations like map, ap, bind, pure, now you just create small objects whith same shape (so JS runtime can optimize property access).
- it could be stack safe by default.
- as Eff is a tree now might be easier to debug (like you can print it).