This repository was archived by the owner on Oct 4, 2020. It is now read-only.
This repository was archived by the owner on Oct 4, 2020. It is now read-only.
free-ish representation of Eff in JS #29
Open
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 tounsafeRun
and 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).
Metadata
Metadata
Assignees
Labels
No labels