
Thanks for the ideas, Adam. I still have a few questions. Adam Bergmark wrote:
The reason my is available in the lambda \x -> my >>= \y -> W (x+y) has to do with scoping rules, Haskell (and almost all programming languages) use static scoping, meaning a variable defined in an outer function is available in the inner function, for instance, (\a -> \b -> (a,b)) 1 2 will evauate to (1,2) since a is bound to 1 in the outer lambda, and the inner one can refer to the outer one, if instead you write (\a -> \a -> (a,a)) 1 2 the result will be (2,2) since the innermost a will be used (no ambiguity here, but if shadowing is done by accident it can be hard to find the error).
Because the lambda is executed by the implementation of >>=, doesn't the concept closure still apply? That value of 'my' has to "get into" the other routine. I am aware that other languages have closures, but in Python they are an advanced, rarely explored concept, so I haven't gotten a good intuition for them. (I don't mean to imply I've only programmed in Python---also Lisp and C++, but only to do boring things, never anything sophisticated from a CS point of view.) It's not that I don't understand the use of 'my'---it's just that it didn't occur to me at first.
The book Structure and Interpretation of Computer Programs (freely available online) discusses this subject in detail.
= is available inside the lambda for the same reason, >>= is imported into the modules namespace, and therefore available everewhere, unless a shadowing binding exists.
The problem is not that I didn't expect >>= to be outside the namespace. The problem is that I am still having to "unlearn" imperative concepts, so it was all too easy to think of >>= as an imperative concept, and in Python procedural statements are not allowed inside lambdas. Also, in the early stages of learning Haskell there are no monads used inside lambdas. So it's not that anyone told me I couldn't do it, just that it didn't occur to me the first time I saw the problem. There is no great revelation here, other than my own satisfaction at seeing a little deeper into the way things are done in Haskell, and finding these problems much easier after revisiting them (I didn't do anything Haskell for a couple months, and just came back to it). -Mike