无法理解列表推导式

2024-02-21

我刚刚开始学习 haskell(字面意思是今晚!)并且我在理解列表理解的逻辑时遇到了一些困难,更具体地说是<-操作员。一个小例子学习一些 Haskell http://learnyouahaskell.com/starting-out查找长度小于 10 的所有元组:

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

我最初的理解是这些都会一起增加,但是在看到输出后我真的不明白递增这些列表的方法。另一个让我感兴趣的例子是:

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

我真的很感谢对这些问题的一些解释,感谢您对我缺乏哈斯克尔智能的耐心。


Read [作为“列表”,|至于”,<-作为“在”,,作为“和”。

枚举是在nested时尚。[ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2]是真的

for c from 1 to 10 step 1:
   for b from 1 to c step 1:
      for a from 1 to b step 1:
          if (a^2 + b^2 == c^2):
             emit (a,b,c)

但在 Haskell 中,上述内容是通过以下翻译实现的

[1..10] >>= (\c->               -- (a function of 'c', producing ...
  [1..c]  >>= (\b->               -- (a function of 'b', producing ...
    [1..b]  >>= (\a->               -- (a function of 'a', producing ...
      if a^2+b^2==c^2 then [(a,b,c)] else []
      -- or: [(a,b,c) | a^2+b^2==c^2]
      )))

所以你真的可以在这里看到嵌套结构。(>>=)也没什么神秘的。读>>=尽管其正式名称是“绑定”,但它被称为“馈入”或“推入”。它(对于列表)定义为

(xs >>= f) = concatMap f xs = concat (map f xs)

f这里被称为(由map) 对每个元素xs, 为了。它必须产生lists这样它们就可以与concat。由于列表为空[]被淘汰于concat (e.g. concat [[1], [], [3]] == [1,3])所有未通过测试的元素都会从最终输出中消除。


完整翻译请参见第 3.11 节,列表推导式 http://www.haskell.org/onlinereport/exps.html#sect3.11,Haskell 98 报告。一般来说,列表推导式可能包含模式,而不仅仅是变量名。领悟

[e | pat <- ls, ...]  

被翻译为

ls >>= (\x -> case x of pat -> [e | ...] ;
                        _   -> [] )

where pat是某种模式,并且x是一个新鲜变量。当模式不匹配时,会生成一个空列表(而不是运行时错误),并且该元素x of ls被跳过。这对于额外的基于模式的过滤很有用,例如[x | Just x <- ls, even x]哪里所有的Nothings in ls都被悄悄忽视。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无法理解列表推导式 的相关文章

  • Haskell 中的 print 是纯函数吗?

    Is print在 Haskell 中是纯函数 为什么或者为什么不 我认为不是 因为它并不总是返回与纯函数应返回的值相同的值 类型的值IO Int并不是真正的Int 它更像是一张纸 上面写着 嘿 Haskell 运行时 请生成一个Int如此
  • 搜索重写规则

    有什么办法可以浏览或搜索重写规则吗 当我使用像这样的标志时 ddump rule firings or ddump rule rewrites我只是得到了触发的规则的名称以及它引起的重写 但没有得到实际的规则本身 理想情况下 我想通过 GH
  • 使用 FoldLine 解析多个块

    对于这个简化的问题 我试图解析一个如下所示的输入 foo bar baz quux woo hoo xyzzy glulx into foo bar baz quux woo hoo xyzzy glulx 我尝试过的代码如下 import
  • Haskell 中列表列表的笛卡尔积

    给定一个长度列表的列表x所有子列表的长度都相同y 输出y x长度列表x包含每个子列表中的一项 例子 x 3 y 2 1 2 3 4 5 6 Output 2 3 8不同的输出 1 3 5 1 4 5 1 3 6 1 4 6 2 3 5 2
  • Haskell 中的中缀运算符优先级

    对于以下 Haskell 表达式 返回 a gt gt f 应该读作 返回a gt gt f or 返回 a gt gt f 这里的相关规则是什么 规则始终是函数应用程序的优先级高于任何运算符 因此 return a gt gt f 被解析
  • Haskell Stack 从 github 安装包依赖项

    是否可以使用 Haskell 堆栈从 github 安装软件包的版本 例如在一个 cabal or a stack yaml文件 如何在 git repo branch revision 上指向依赖项 对于堆栈 The 的文档stack y
  • 有没有更好的方法将 UTC 时间转换为大纪元时间?

    我想将文件的修改时间设置为从 exif 数据获取的时间 为了从 exif 获取时间 我发现 Graphics Exif getTag Exif gt String gt IO Maybe String 要设置文件修改时间 我发现 Syste
  • Python 循环的列表理解

    我使用了很多 N 维数组 编写这样的缩进代码会很痛苦 而且我知道有些代码可以用列表理解和内联语句替换 例如 for x in 0 1 2 3 for y in 0 1 2 3 if x lt y print x y x y 可以替换为 pr
  • Haskell:IORef 的性能

    我一直在尝试在 Haskell 中编码一个需要使用大量可变引用的算法 但与纯粹的惰性代码相比 它 也许并不奇怪 非常慢 考虑一个非常简单的例子 module Main where import Data IORef import Contr
  • 如何通过“cabal build”或“stack build”构建带有图标的项目

    我想构建一个带有图标的可执行文件 通过谷歌搜索 我发现这里的说明 https wiki haskell org Setting an executable icon 但它只能通过编译源文件来工作ghc 如果我想构建一个具有可执行文件的项目c
  • Data.Sequence 中的 inits 和 tails 如何工作?

    Louis Wasserman 编写了当前的实现inits and tails in Data Sequence 他表示它们非常高效 事实上 只要查看代码 我就可以看到 无论它们在做什么 它们都是以干净 自上而下的方式进行的 这往往会给惰性
  • 不同编程语言中的浮点数学

    我知道浮点数学充其量可能是丑陋的 但我想知道是否有人可以解释以下怪癖 在大多数编程语言中 我测试了 0 4 到 0 2 的加法会产生轻微的错误 而 0 4 0 1 0 1 则不会产生错误 两者计算不平等的原因是什么 在各自的编程语言中可以采
  • Haskell Data.Decimal 作为 Aeson 类型

    是否可以解析一个数据 十进制 https hackage haskell org package Decimal 0 4 2 docs Data Decimal html使用 Aeson 包从 JSON 获取 假设我有以下 JSON foo
  • 如何打乱列表?

    如何从一组数字 1 2 3 直到我击中x 我的计划是重新调整列表 1 2 3 并把它砍在x chopAt 3 2 3 1 2 3 chopAt 3 2 1 3 2 1 3 chopAt 3 3 1 2 3 chopAt chopAt x y
  • 如何更换HXT中的节点?

    给定一个示例 xml 文件
  • 关于“没有绑定的类型签名”的错误

    我在 Haskell 中遇到 ASCII 问题 fromEnum Char gt Int toEnum Int gt Char offset Int offset fromEnum A fromEnum a toUpper Char gt
  • 纯 Haskell 代码需要线程池吗?

    In 现实世界 Haskell 第 28 章 软件事务内存 http book realworldhaskell org read software transactional memory html 开发了一个并发网络链接检查器 它获取网
  • 使用带有两个列表而不是一个列表的地图。可以筑巢吗?

    我需要多次运行一个带有两个参数的函数 我有两个包含这些参数的列表 我希望能够使用map或类似的东西用相应的参数调用函数 我要调用的函数具有以下类型 runParseTest String gt String gt IO 列表的创建方式如下
  • Parsec.Expr 具有不同优先级的重复前缀

    Parsec Expr buildExpressionParser 的文档说 相同优先级的前缀和后缀运算符只能出现一次 即 如果 为前缀否定 则不允许使用 2 但是 我想解析这样的字符串 具体来说 考虑以下语法 sentence ident
  • 自定义 monad 的 MonadTransControl 实例

    的文档monad control提供有关如何创建实例的示例MonadTransControl using defaultLiftWith and defaultRestoreT 该示例适用于以下情况newtype newtype Count

随机推荐