Haskell 列表理解 - 直角三角形
Haskell List Comprehension - Right Angled Triangles
我目前正在从 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)]
我会通过以下方式产生这个结果:
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]
.
发生了什么
如果有人能解释正在发生的事情,我将不胜感激,如果可能的话,也许可以提供某种插图。我对函数式编程还很陌生,真的很想了解它是如何工作的。
谢谢!
简答:因为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, <b>c+1</b>):
for a in range(1, <b>b+1</b>):
if a*a + b*b == c*c:
data.append((a, b, c))
您可以将其视为一种循环机制,其中为变量 c
、b
和 a
分配了值。
因为它被实现为b <- [1 .. c]
,这意味着b
是小于或等于到c
,因为那是范围的最大界限。
由于该技巧也适用于 a <- [ 1 .. b]
,这意味着对于我们考虑的所有三元组,a ≤ b ≤ c。由于a ≥ 1,也意味着b ≤ c如果满足约束a2+b2=c2,表示a < c 和 b< c,因为如果 b 例如是一个,则意味着 a2 + 1 = b2,a同理。所以我们知道 a < c 和 b < c.
a
也不能等于b
。如果是这样,则意味着 2×a2 = c2,因此表示 c = √2×a。由于a
、b
和c
都是整数值,所以不可能a = b
,因为c
不可能是整数,因为一个整数乘以一个无理数是一个无理数。
我目前正在从 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)]
我会通过以下方式产生这个结果:
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]
.
如果有人能解释正在发生的事情,我将不胜感激,如果可能的话,也许可以提供某种插图。我对函数式编程还很陌生,真的很想了解它是如何工作的。
谢谢!
简答:因为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, <b>c+1</b>):
for a in range(1, <b>b+1</b>):
if a*a + b*b == c*c:
data.append((a, b, c))
您可以将其视为一种循环机制,其中为变量 c
、b
和 a
分配了值。
因为它被实现为b <- [1 .. c]
,这意味着b
是小于或等于到c
,因为那是范围的最大界限。
由于该技巧也适用于 a <- [ 1 .. b]
,这意味着对于我们考虑的所有三元组,a ≤ b ≤ c。由于a ≥ 1,也意味着b ≤ c如果满足约束a2+b2=c2,表示a < c 和 b< c,因为如果 b 例如是一个,则意味着 a2 + 1 = b2,a同理。所以我们知道 a < c 和 b < c.
a
也不能等于b
。如果是这样,则意味着 2×a2 = c2,因此表示 c = √2×a。由于a
、b
和c
都是整数值,所以不可能a = b
,因为c
不可能是整数,因为一个整数乘以一个无理数是一个无理数。