I wanted to make a brief note about colored functions and monadic effects.
A mother of monads is a codensity monad. For category theorists, there is a slogan; "whenever you meet a functor, ask what its codensity monad is."
Codensity monads correspond to types of continuations. One example is given by the basic double-negation translation; instead of values of type X, we have values of type (X → F(R)) → F(R) for some family of types R and some endofunctor F carrying a monadic effect. Given a callback which finalizes X into a chosen R, we may treat the callback as a continuation and invoke it. This is the original mother of all monads, since double-negation translation is almost always available. But there are other types of continuations. If we use single-shot delimited continuations, then the same monadic effects produce different results. Whenever we meet a monadic effect carried by an endofunctor, ask what its continuation is.
Suppose that we asynchronously perform some action and then invoke a callback. The callback acts as a continuation of the action. This generates a codensity monad which can host effects. If it is possible to wait or block for an asychronous action, then there is a lowering operation from the asynchronous codensity monad to the double-negation codensity monad. The effects are still performed with asynchronous continuations, though. This is the sense in which futures, deferreds, promises, and other asynchronous values are elements of a monad; they are available through callbacks, just like values in any other codensity monad.
But if it is not possible to wait for asynchronous actions, then we should probably prefer embedding the plain double-negation monad into the asynchronous monad. In practice, it seems that the effects hosted in the plain codensity monad can be performed asynchronously; it's not clear to me whether there's an underlying natural transformation which makes this possible.
We are now ready to deconstruct the analogy of colored functions. The original observation was that asynchronous actions (in ECMAScript) are not "in" the same codensity monad as plain functions; they must be awaited or otherwise lowered out of the asynchronous context. To each codensity monad, a color is assigned; the original article assigns blue to the plain calling convention, and red to the asynchronous convention.
However, the analogy is incomplete, because monadic effects are confused with their underlying codensity monads; additionally, we should privilege whichever calling convention is used at the top level of the programming interface. This means that, when writing in ECMAScript or other languages with builtin concurrency, asynchronous actions are not colored red but colorless. To restore monadic effects to the analogy, we should tint the colors; let the double-negation monad be blue, and then perhaps a synchronous non-determinism effect is dark blue, while a synchronous error-handling effect is light blue.
When viewed through the reconstructed analogy, monad transformers are recharacterized as effects which are portable to different codensity monads; they are tints without a base color. An important lesson for language designers is to take a desired composite effect and break it apart so that its codensity monad can be cleanly separated from other effects.
This can be justified somewhat by noting that codensity monads are pushouts of identity monads along some functor. Take an identity monad and push it along some effect-carrying functor, and the effects get rolled in, creating a codensity monad.
Some concrete examples might ground this, as at the moment I don’t understand what point you’re trying to make. It reads like markov generated pros, at least to me.