Skip to content

Instantly share code, notes, and snippets.

@dustingetz
Created July 24, 2012 19:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dustingetz/3172127 to your computer and use it in GitHub Desktop.
Save dustingetz/3172127 to your computer and use it in GitHub Desktop.
reader-monad in python
class Monad:
"""provides generic methods like fmap, map, reduce, chain which use polymorphic
implementations of unit and bind"""
pass
class _Reader_m(Monad):
def unit(self, v): return lambda env: v
def bind(self, mv, mf):
def _(env):
val = mv(env)
return mf(val)(env)
return _
reader_m = _Reader_m()
from collections import namedtuple
def _test_reader_m():
Env = namedtuple('Env', ['hostname', 'port', 'outfile'])
def doSomething(hostname, port, outfile):
return [outfile, port, hostname]
# getters describe how to read a value from an environment,
# but do not have access to the environment itself
hostname = lambda env: env.hostname
port = lambda env: env.port
outfile = lambda env: env.outfile
def bootstrap():
"""no dependencies passed as parameters. could have very long list of
dependencies"""
r = reader_m.bind( hostname, lambda h:
reader_m.bind( port, lambda p:
reader_m.bind( outfile, lambda o:
reader_m.unit( doSomething(h,p,o) ))))
return r
env = Env("localhost", 80, "/etc/passwd")
assert bootstrap()(env) == ["/etc/passwd", 80, "localhost"]
_test_reader_m()
@dustingetz
Copy link
Author

hi tony,

I heard your talk "dependency injection without the gymnastics" at PhillyETE. i was the most active questioner.

I've implemented a bunch of monads in python to better understand them. Scroll up for my impl of reader-monad. I'm not concerned with writing out the macroexpansions of a monad comprehension.

you wrote: "OK then, pass arguments through explicitly — bit clumsy innit?" - I'm confused. In my example, I see no value add to the monadic style, we end up passing dependencies as arguments anyway. is the entire bulk of the business logic supposed to be a monad comprehension?

i work in enterprise and understand the pain of DI, but I don't see how this helps. if the dependency is a logger or database connection, its cool that an application can't reach out and grab a singleton--you have to be in the monad--but once the monad injects the dependency, you are still reduced to passing it around in the business logic, which is no different than a runtime passing these dependencies to the business logic entry point. a reader-writer monad stack could guarantee that resource access is logged, but i can provide that guarantee without monads.

thanks for your time.
Dustin Getz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment