Question: I have a quick question about Haskell. I've been following [Learn You a Haskell](http://learnyouahaskell.com/starting-out#tuples), and am just a bit confused as to the execution order / logic of the following snippet, used to calculate the side lengths of a triangle, when all sides are equal to or less than 10 and the total perimeter of the triangle is 24:

`[(a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2, a+b+c==24]`

The part that is confusing to me is the upper expansion bound on the `b` and `a` binding. From what I gather, the `..c` and `..b` are used to remove additional permutations (combinations?) of the same set of triangle sides.

When I run it with the `..c/b`, I get the answer:

`[(6,8,10)]`

When I don't have the `..c/b`:

`[(a,b,c) | c <- [1..10], b <- [1..10], a <- [1..10], a^2 + b^2 == c^2, a+b+c==24]`

as I didn't when I initially typed it in, I got:

`[(8,6,10),(6,8,10)]`

Which is obviously representative of the same triangle, save for the `a` and `b` values have been swapped. 

So, can someone walk me through the logic / execution / evaluation of what's going on here?

Answer: 
The original version considers all triplets (a,b,c) where c is a number between 1 and 10, b is a number between 1 and c and a is a number between 1 and b. (6,8,10) fits that criteria, (8,6,10) doesn't (because here a is 8 and b is 6, so a isn't between 0 and 6).

In your version you consider all triplets (a,b,c) where a, b and c are between 1 and 10. You make no restrictions on how a, b and c relate to each other, so (8, 6, 10) is not excluded since all numbers in it are indeed between 1 and 10.

If you think of it in terms of imperative for-loops, your version does this:

```
for c from 1 to 10:
  for b from 1 to 10:
    for a from 1 to 10:
      if a^2 + b^2 == c^2 and a+b+c==24:
        add (a,b,c) to the result

```

while the original version does this:

```
for c from 1 to 10:
  for b from 1 to c:
    for c from 1 to b:
      if a^2 + b^2 == c^2 and a+b+c==24:
        add (a,b,c) to the result

```
List comprehensions can be written in terms of other functions like `concatMap`, which clarifies the scope of the bindings. As a one-liner, your example becomes something like this:

```
concatMap (\c -> concatMap (\b -> concatMap (\a -> if a^2 + b^2 == c^2 then (if a+b+c == 24 then [(a,b,c)] else []) else []) (enumFromTo 1 b)) (enumFromTo 1 c)) (enumFromTo 1 10)

```

Yeah, that looks ugly, but it's similar to what Haskell desugars your comprehensions into. The scope of each of the variables `a`, `b` and `c`, should be obvious from this.

Or alternatively, this can be written with the `List` monad:

```
import Control.Monad

example = do c <- [1..10]
             b <- [1..c]
             a <- [1..b]
             guard (a^2 + b^2 == c^2)
             guard (a+b+c == 24)
             return (a,b,c)

```

This is actually very similar as the one-liner above, given the definition of the `List` Monad and `guard`:

```
instance Monad [] where
    return x = [x]
    xs >>= f = concatMap f xs

instance MonadPlus [] where
    mzero = []
    mconcat = (++)

guard bool = if bool then return () else mzero

```