Home > Net >  How To Write a Monad to Chain Computations Together
How To Write a Monad to Chain Computations Together

Time:03-04

I am writing my first monad instance so please forgive if I'm missing something obvious.

I want to do something like this:

readStuffFromDatabase >>= function1 >>= ... >>= functionN >>= writeStuffToDatabase

function1 ... functionN are business logic. Any business logic can return DoNothing which should obviously prevent any further computation.

Here are my questions:

  1. Am I thinking about the problem in the right way? Can this approach lead to idiomatic code, good performance, etc. or is it already doomed?

  2. How should I define a type intended to chain arbitrary amounts of computation together? What's fuzzy to me is do all monad instances already do that and all I need is a vanilla monad instance? (Like Maybe?) Or do I need something more sophisticated?

CodePudding user response:

Short version: Monad is almost certainly going to paint you into a corner. You need Applicative instead, or at most, a selective applicative.

Suppose you go for a monad, name it M, and have some action like numEmployees :: M Int or something. Now I write:

do
    n <- numEmployees
    if n > 10
        then computeTaxes
        else dollars 1000 <$ DoNothing

To execute this action, you need to decide whether the else branch gets taken before knowing n. Not possible.

The fundamental feature of monads that's in your way here is that later actions can inspect the values returned by earlier actions before deciding what to do. Applicative functors do not support that, and so are more amenable to the kind of static analysis you're hoping to do.

  • Related