On 1/17/11 12:22 PM, Tyson Whitehead wrote:
> On January 15, 2011 22:43:32 Jan-Willem Maessen wrote:
>> For example, I find it relatively easy to
>> understand>>= in the continuation monad, but have to spend a long
>> time puzzling my way through join.
>> It's not that bad once you get used to thinking of it. Join simply merges an
> inner computation into an outer one.
I've been doing a lot more of that lately, or rather _not_ doing it. In
particular, there's often a desire when working in monads like IO to do
some computation now (and share it) and then do some computation later
(possibly many times). The natural way of doing this is to have your
function return IO(IO X) where the outer IO is run now and the inner IO
is run later. If you want to do both of them now you just call join.
One example where this is especially helpful is when dealing with file
handling based on commandline flags. In most programs we'd like to run
the commandline sanity checks as early as possible so that we can fail
fast, but the actual file manipulation can happen much later and far
away from main. In the conventional (>>=) style of thinking ---often
seen in imperative languages--- we'd have to do something like open the
files early and then pass filehandles throughout the program (or worse,
pass the file names throughout the program and open/close the files
repeatedly). This is not only against what we'd like to do, it's also
unsightly, error prone, and a maintenence nightmare.
But once we switch over to a join style of thinking, the IO(IO X)
approach becomes obvious. We simply check the flags now and return a
thunk that will manipulate the file later. We have to pass the thunk
around, but the action encapsulates whatever we want to do with the file
rather than being the file itself. An added benefit of this style is
that it allows us to keep the code that verifies commandline flags close
by the code that makes use of that information, instead of smearing it
across the whole program and loosing track of the interrelatedness.
--
Live well,
~wren