[Haskell-cafe] Is the Haskell list comprehension just a Cartesian product machine?
Albert Y. C. Lai
trebla at vex.net
Wed Dec 8 02:46:48 UTC 2021
On 2021-12-07 9:10 p.m., Galaxy Being wrote:
> If I were a teacher of high-schoolers wanting to add some theory to
> Haskell could I explain Haskell list comprehensions as basically just a
> Cartesian/cross product machine? Would this be accurate? And then the
> combinatorics product rule also seems at play here. I would appreciate
> any theoretical explanation of what a list comprehension is about.
Short answer is yes.
Level 1:
[ (x,y) | x <- [1,2], y <- [3,4,5] ]
is a cartesian product. This corroborates with that <*> for list does
cartesian product, i.e.,
pure (,) <*> [1,2] <*> [3,4,5]
And replacing (x,y) by arbitrary f x y does not really change the story.
Level 2:
[ (x,y) | x <- [1,2], y <- [x .. x+x] ]
Do you call that a cartesian product?
I would call it a dependent cartesian product.
{1,2} x (this set depends on the 1 or 2)
On the bright side, I think high-schoolers are flexible enough to accept
this as a kind of cartesian product, too.
This corroborates with that >>= for list does dependent cartesian
product, i.e.,
[1,2] >>= \x -> [x .. x+x] >>= \y -> pure (x,y)
Again, replacing (x,y) by arbitrary f x y does not really change the story.
Level 3:
Will you also tell your students about this?
[ (x,y) | x <- [1,2], x > 1, y <- [x .. x+x], y < 3 ]
Some kind of wacky cartesian product that's both dependent and conditional.
This needs empty from Alternative or mzero from MonadPlus:
Define (already in Control.Monad):
guard c = if c then pure () else empty
[1,2] >>= \x ->
guard (x > 1) >>
[x .. x+x] >>= \y ->
guard (y < 3) >>
pure (x,y)
{1,2} x (this set depends on the 1 or 2, can be empty) x ...
Have fun.
More information about the Haskell-Cafe
mailing list