【问题标题】:Using list comprehension with two variables in haskell在haskell中使用带有两个变量的列表推导
【发布时间】:2021-03-11 19:32:04
【问题描述】:

有人知道我如何在 haskell 中使用两个变量进行列表理解吗?

例如。

[ x * y  | x <- [1..10]  y <- [1..10]]

它应该导致

[1,4,9,16,25,36,49,64,81,100]

但它实际上在 ghci 中产生

<interactive>:13:23-24: error:
    parse error on input ‘<-’
    Perhaps this statement should be within a 'do' block?

【问题讨论】:

  • 生成器用逗号分隔,所以[ x * y | x &lt;- [1..10], y &lt;- [1..10]] 会输入检查,但不会给你想要的输出。 [x * x | x &lt;- [1..10]] 可以工作,但只需要一个生成器。
  • 谢谢!这真的很有帮助!

标签: haskell functional-programming list-comprehension


【解决方案1】:

这里有两个问题:一个句法,一个语义

迈向有效的列表理解表达式

语法上的一个是用 逗号 ( ,)

[ x * y  | x &lt;- [1..10]<b>,</b> y &lt;- [1..10]]

但现在我们将不会获得所需的输出。确实:

Prelude> [ x * y  | x <- [1..10], y <- [1..10]]
[1,2,3,4,5,6,7,8,9,10,2,4,6,8,10,12,14,16,18,20,3,6,9,12,15,18,21,24,27,30,4,8,12,16,20,24,28,32,36,40,5,10,15,20,25,30,35,40,45,50,6,12,18,24,30,36,42,48,54,60,7,14,21,28,35,42,49,56,63,70,8,16,24,32,40,48,56,64,72,80,9,18,27,36,45,54,63,72,81,90,10,20,30,40,50,60,70,80,90,100]

我们这里有从110 的两个整数之间的所有乘法。因为对于列表[1..10] 中的每个x,我们遍历列表[1..10] 以获得y。然而,这与您请求的列表不匹配,因此存在语义错误。

获取方块列表

您似乎想要的是所有 square 数字的列表。在这种情况下,只有一个变量x,对于x的每个值,我们产生x*x

[ x * x  | x &lt;- [1..10]]

然后产生:

Prelude> [ x * x  | x <- [1..10]]
[1,4,9,16,25,36,49,64,81,100]

并行枚举列表

如果您有两个要并行枚举的列表,您可以使用zip 执行此操作,例如,如果我们要将[1..10] 的元素与[5..14] 的元素相乘 elementwise ,我们可以这样做:

[ x * y  | (x, y) &lt;- zip [1..10] [5..14]]

我们也可以将ParallelListComp extension 用作@DanielWagner says

{-# LANGUAGE ParallelListComp #-}

[ x * y  | x <- [1..10] | y <- [5..14]]

【讨论】:

  • 可能值得一提的是ParallelListComp[x*y | x &lt;- [1..10] | y &lt;- [1..10]]
【解决方案2】:

您需要将两个范围压缩在一起:

[ x * y | (x, y) <- zip [1..10] [1..10] ]

可以有两个独立的迭代器,用逗号分隔

[ x * y | x <- [1..10], y <-[1..10] ]

但这会计算两组的笛卡尔积,从而得到一个完整的乘法表,而不是一个平方列表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-30
    • 1970-01-01
    • 2022-11-08
    • 1970-01-01
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多