Haskell 如何在列表中计算相关范围?
我现在正在努力,我对中倒数第二个例子感到困惑 作为一种生成三元组的方法,表示所有边都是小于或等于10的整数的所有直角三角形,他给出了以下定义:Haskell 如何在列表中计算相关范围?,haskell,list-comprehension,evaluation,Haskell,List Comprehension,Evaluation,我现在正在努力,我对中倒数第二个例子感到困惑 作为一种生成三元组的方法,表示所有边都是小于或等于10的整数的所有直角三角形,他给出了以下定义: rightTriangles = [ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2] rightTriangles=[(a,b,c)| c鉴于您有命令式编程的经验,简短的回答是:对于嵌套(伪代码),与此类似: >(c=1;c)让我们考虑两个更简
rightTriangles = [ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2]
rightTriangles=[(a,b,c)| c鉴于您有命令式编程的经验,简短的回答是:对于嵌套(伪代码),与此类似:
<代码> >(c=1;c)让我们考虑两个更简单的列表理解:
ex1 = [(a,b) | a <- [1..3], b <- [1..3]]
ex2 = [(a,b) | a <- [1..3], b <- [1..a]]
ex1 = concat [ [(a,b) | b <- [1..3]] | a <- [1..3] ]
ex2 = concat [ [(a,b) | b <- [1..a]] | a <- [1..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,这个答案有些让我不知所措,但由于第一个非常清晰的例子,我完全理解了核心概念。随着我在Haskell的进步,我会回到这一点上,并希望得到平衡更多信息。无论如何,谢谢你!整体回答很好!
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) ]
ex1 = concat [ [(a,b) | b <- [1..3]] | a <- [1..3] ]
ex2 = concat [ [(a,b) | b <- [1..a]] | a <- [1..3] ]
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]
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]
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)
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.
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`