Haskell 列表理解 - 直角三角形

Whi*_*bra 5 haskell functional-programming list-comprehension

我目前正在从Learn You a Haskell for Great Good学习 Haskell 书。示例之一涉及创建表示三角形的 3 项元组:

let triangles = [ (a,b,c) | c <- [1..10], b <- [1..10], a <- [1..10] ]

然后我们对原始列表推导式应用一些条件,只创建直角三角形:

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

制作结果:

ghci> rightTriangles
[(3,4,5),(6,8,10)]
Run Code Online (Sandbox Code Playgroud)

我会通过以下方式产生这个结果:

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

谁能解释一下教程的直角代码是如何工作的?这两种方法都应用过滤器来确保这一点,a < b && b < c但我无法准确描绘 c <- [1..10], b <- [1..c], a <- [1..b].

如果有人可以解释正在发生的事情,我将不胜感激,如果可能的话,也许可以提供某种说明。我对函数式编程很陌生,真的很想了解它是如何工作的。

谢谢!

Wil*_*sem 6

简短回答:因为b <- [ 1 .. c ]这意味着b总是小于或等于c.

c <- [1..10]b <- [1..c]并且a <- [1..b]是发电机。在 Python 中,这看起来像一个 for 循环,所以类似于;

data = []
for c in range(1, 11):
    for b in range(1, c+1):
        for a in range(1, b+1):
            if a*a + b*b == c*c:
                data.append((a, b, c))
Run Code Online (Sandbox Code Playgroud)

你可以看到这是一个循环的机制,其中的变量cb以及a为指定的值。

因为它是作为实现b <- [1 .. c],这意味着,b小于或等于c,因为这是结合的范围的最大。

由于该技巧也适用于a <- [ 1 .. b],这意味着对于我们考虑的所有 3 元组,a ? 乙?丙。从? 1、这也意味着b ? c如果它满足约束a 2 +b 2 =c 2,则意味着a < cb< c,因为如果b例如为 1,则意味着a 2 + 1 = b 2,同样适用于a . 所以我们知道a < cb < c

a也不能等于b。如果是这种情况,则意味着2×a 2 = c 2,因此这意味着c = ?2×a。由于abc都是整数值, 不可能a = b, 因为 thenc不能是整数, 因为整数乘以无理数是无理数。