How are dependent ranges defined in list comprehension?

I am currently going through Teach you Haskell for Great Good! , and I got confused in the penultimate example in Chapter 2 .

As a way to create triples representing all right triangles with all sides that are integers less than or equal to 10, he gives this definition:

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

What confuses me especially is the fact that it is btied to a list that ranges from 1 to c, and similarly to a. If my understanding is correct, it cwill be evaluated by all the values ​​in the list to which it is attached, but I still don’t see what value is used for cin the range (for example, all values c, only the first c, etc.)

If it's not so much, a step-by-step explanation of how it is rated will be great. :)

Thanks in advance!

+5
source share
2 answers

Consider two simple list comprehensions:

ex1 = [(a,b) | a <- [1..3], b <- [1..3]]

ex2 = [(a,b) | a <- [1..3], b <- [1..a]]

, b 1 a, 1 3. , ; , .

ex1 = [ (1,1), (1,2), (1,3)
      , (2,1), (2,2), (2,3)
      , (3,1), (3,2), (3,3) ]

ex2 = [ (1,1),
      , (2,1), (2,2),
      , (3,1), (3,2), (3,3) ]

[1..3] [1..3]. , , , , . , , ex1:

  • a .
    • a b - .
      • (a,b) -

, : " a, (a,b) b." , :

  • a 1, , b.
  • a 2, b.
  • , , a 3, b.

. a, b . :

  • -, a 1, , b. b <- [1..a], b <- [1..1], .
  • , a 2, , b. b <- [1..2], .
  • , a 3, b <- [1..3]; .

, , . - :

ex1 = concat [ [(a,b) | b <- [1..3]] | a <- [1..3] ]

ex2 = concat [ [(a,b) | b <- [1..a]] | a <- [1..3] ]

, a <- [1..3] ; , b , a s. , , , b a. ( Haskell 2010):

ex1 = concatMap (\a -> [(a,b) | b <- [1..3]]) [1..3]
    = concatMap (\a -> concatMap (\b -> [(a,b)]) [1..3]) [1..3]

ex2 = concatMap (\a -> [(a,b) | b <- [1..a]]) [1..3]
    = concatMap (\a -> concatMap (\b -> [(a,b)]) [1..a]) [1..3]

, , . -, , , a , , . , rightTriangles

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

rightTriangles :

import Control.Monad (guard)

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

, do , , -, IO, , . x <- list " x list", :

rightTriangles = do
  c <- [1..10]             -- For each `c` from `1` to `10`, ...
  b <- [1..c]              -- For each `b` from `1` to `c`, ...
  a <- [1..b]              -- For each `a` from `1` to `b`, ...
  guard $ a^2 + b^2 == c^2 -- If `a^2 + b^2 /= c^2`, then `continue` (as in C);
  return (a,b,c)           -- `(a,b,c)` is the next element of the output list.

, continue .

rightTriangles = do c <- [1..10]
                    b <- [1..c]
                    a <- [1..b]
                    if a^2 + b^2 == c^2
                      then return (a,b,c)
                      else [] -- or `mzero`

"if a^2 + b^2 == c^2, (a,b,c) , ". , , , , " " , , do -notation 2 "Learn You A Haskell": )

+13

, , : for nesting ():

for(c = 1; c <= 10; c++) {
    for(b = 1; b <= c; b++) {
        for(a = 1; a <= b; a++) {
            if(a ^ 2 + b ^ 2 == c ^ 2) {
                list.append((a, b, c));
            }
        }
    }
}
+6

All Articles