Relative to the fish operator, Monads satisfy associativity.
(h >=> g) >=> f = h >=> ( g >=> f)
This translated to bind (with lambda expressions) looks like,
\a -> h a >>=(\b -> g b >>= \c -> f c) = \a ->(h a >>= \b -> g b)>>= \c -> f c
which means the following equation is unambiguous
( a -> h a >>= \b -> g b >>= \c -> f c ) = h >=> g >=> f
This is a nice way to understand Monadic composition.
However not all Monadic code keeps the bound variables to the lambdas separated. For example,
[1,2] >>= \n -> ['a','b'] >>= \ch -> return (n,ch) = [(1,'a'),(1,'b'),(2,'a'),(2,'b')]
The "n" in the return was obtained from the top lambda.
a -> g a >>= \b -> f a b
f depends on both a and b in the above. Defining the above in terms of f, g, and (>=>) gives
\a -> (\x -> g a) >=> f a
Which I don't understand very well. It doesn't match the above equation I showed very well. I see fish as the fundamental notion here, and I'm trying to understand how it interacts with typical Monads I write. I would like to understand the above better.
One way of approaching this is by trying to obtain meaning from List expression syntax
[ (n,ch) | n <- [1, 2], ch <- ['a', 'b'] ]
I think this implies a kind of symmetry.
Are there any nice symmetries connecting lambda expressions and Monads? Or am I reading too much into this? Is my fear of highly nested lambda expressions wrong or reasonable?