> It amazes me that Haskell takes my Python hack and actually allows it to be expressed quite naturally!
This isn't an accident. Python's list comprehensions were modeled on Haskell's list comprehensions, which were in turn modeled on the much more general concepts of monads. Haskell's do notation provides a nice syntactic sugar for monadic code. Since lists form a monad, such code is quite naturally expressed using do notation.
Haskell's list comprehensions can be directly translated to do notation
[x+y | x <- [1..10], y <- [1..10], x+y<5]
can be translated into
do x <- [1..10]
y <- [1..10]
guard (x+y<5)
return (x+y)
> Python's list comprehensions were modeled on Haskell's list comprehensions, which were in turn modeled on the much more general concepts of monads.
It's true that Python borrowed the concept from Haskell.
But Haskell in turn took the concept from set theory, not category theory.
List comprehensions are modeled after set comprehensions. Here's an example that uses set-builder notation [0] to define the set of Pythagorean triples with sides bounded by 10:
let u=[1..10] in [ (x,y,z) | x<-u,y<-u,z<-u, x^2 + y^2 = z^2 ]
The creators of Haskell worked hard to make sure the syntax was a spitting image of set theory.
For a motivation behind the creation of Haskell was to use it to as a lightweight calculator / computer algebra system (sans heavy algebra) to teach set theory to students.
List comprehensions have been around since the dawn of Haskell. It was around even before Haskell, viz. in Miranda circa mid-80s.
Moggi's work on PL monads was only published in 1991.
I think you've mixed up monad comprehensions--which came much later--which is the observation that this notation and concept can be generalized to monads other than lists. Monad comprehensions segue into topos theory, understood as a monadic generalization of set theory, quite nicely.
Hopefully, the next 700 monad tutorials will give more visibility to topos theory.
This isn't an accident. Python's list comprehensions were modeled on Haskell's list comprehensions, which were in turn modeled on the much more general concepts of monads. Haskell's do notation provides a nice syntactic sugar for monadic code. Since lists form a monad, such code is quite naturally expressed using do notation.
Haskell's list comprehensions can be directly translated to do notation
can be translated into which is syntactic sugar for where (>>=) is the monadic bind operator.