Skip to content
Dinko Srkoč edited this page Aug 7, 2011 · 4 revisions

The reader monad is also know as the environment monad. It lets our functions read from the environment the data they need to perform the computations. So, the reader monad is like the State monad, with the state being read-only.

Use case: we have functions that operate on certain arguments. Those arguments should be taken from the configuration which is represented by the Config object. We need a way to force our functions to read that object.

import static hr.helix.monadologie.MonadComprehension.foreach

// the configuration class
@Immutable
class Config {
    String hostname
    Integer port
}

// making functions use the Config object
def liftConfigReader = { Closure fn ->
    def hostname = { cfg -> cfg.hostname },
        port = { cfg -> cfg.port }

    foreach {
        h = takeFrom { hostname }
        p = takeFrom { port }

        yield { fn(h, p) }
    }
}

// function that operates on arguments which should be read from the configuration
def showHostAndPort = { host, port ->
    "Host is $host, listening on a port $port"
}

// now, making the function read the config
def cfgShow = liftConfigReader(showHostAndPort)

def cfg = new Config("myhost", 105) // ... the configuration object
println cfgShow(cfg)                // no static dependencies on global configuration

This way, we needn't have static dependencies on global configuration objects.

Clone this wiki locally