2 ms·
It's debatable how much one is willing to describe historical solutions like MTL style to be a "good" solution to this problem (I explained the downsides in my
by tome 4mo ago
It's debatable how much one is willing to describe historical solutions like MTL style to be a "good" solution to this problem (I explained the downsides in my talk "A History of Effect Systems"[1] at Zurihac 2025), but I certainly have no hesitation in describing my capability-based effect system Bluefin[2], as a good solution.
For the channels you describe above the type signature would look like this
Yield String e1 -> -- stdout
Await String e2 -> -- stdin
Yield String e3 -> -- logging
Network e4 -> -- network
Database e5 -> -- database
FileSystem e6 -> -- file system
Eff es r
Six different capabilities that give you access to six different channels of IO. A "Yield" to which you yield strings to stdout, an "Await" from which you can await strings from stdin, a "Yield" to which you yield log messages, and three abstract effects that allow you to do network, database and file system operations (abstract because I'm not sure exactly how you want them defined, but there's an example of the implementation of a file system effect at https://hackage-content.haskell.org/package/bluefin-0.6.0.0/docs/Bluefin-Compound.html#g:11 https://hackage-content.haskell.org/package/bluefin-0.6.0.0/...).
No problem with combining or untangling monads whatsoever. This is the natural conclusion of galaxyLogic's point: instead of dividing your program into two parts (IO and not IO) you divide it into six parts (or maybe 2^6 parts?) according to which fine grained effects you have in scope.
If you (or anyone) has any questions about Bluefin I'm happy to help. Please feel free to ask here or on the issue tracker[3].
[1] https://www.youtube.com/watch?v=RsTuy1jXQ6Y https://www.youtube.com/watch?v=RsTuy1jXQ6Y
[2] https://hackage.haskell.org/package/bluefin https://hackage.haskell.org/package/bluefin
[3] https://github.com/tomjaguarpaw/bluefin/issues/new https://github.com/tomjaguarpaw/bluefin/issues/new
- galaxyLogic 4mo agoInteresting. Those channels seem to all manage side-effects that persist after program execution. What about state-changes that are made and persist into the memory of the running program? Or is there any need for that?
- tome 4mo agoYes, there's a need for it, and Bluefin provides Modify which allows you to modify a reference to a value in a way that is not observable outside the scope of the capability. https://hackage-content.haskell.org/package/bluefin-0.6.0.0/docs/Bluefin-Capability-Modify.html https://hackage-content.haskell.org/package/bluefin-0.6.0.0/...