`
willzh
  • 浏览: 300817 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

我是List comprehension-haskell趣学指南

阅读更多

我是List comprehension-haskell趣学指南

259个读者 ssword @ yeeyan.com 12/11/2008 双语对照   原文 字体大小

简介

关于list comprehension

我是List Comprehension


frog
如果您学过数学,那对集合的comprehension概念一定不会陌生。通过它,可以从既有的集合中按照规则产生一个新集合。产生前十个偶数的集合comprehension可以表示为set notation ,竖线左端的部分是输出函数,x是变量,N是输入集合,x<=10是限制条件。这就表示这个集合中包含了所有符合该限制条件的自然数的二倍。

在haskell下,我们可以通过类似take 10 [2,4..]的代码来实现。但若是把简单的乘2改成更复杂的函数操作该怎么办呢?用list comprehension,它与集合的comprehension十分的相似,立马就可以取到前十个偶数。这个list comprehension可以表示为: [x*2 | x <- [1..10]]。x取自[1..10],遍历[1..10]中的每个元素(使之作为x),并得到该元素使之乘2,如下便是该list comprehension的执行结果:

ghci>  [x*2  |  x <-  [1 ..10 ]]  
[2 ,4 ,6 ,8 ,10 ,12 ,14 ,16 ,18 ,20 ]


如你所见,结果正确。给这个comprehension再添个限制条件,它与前面的条件由一个逗号分隔。在这里,我们要求只取乘以2后大于等于12的元素。

ghci>  [x*2  |  x <-  [1 ..10 ], x*2  >=  12 ]  
[12 ,14 ,16 ,18 ,20

cool,灵了。若是取50到100间所有除7的余数为3的元素该怎么办?简单:

ghci>  [ x  |  x  <-  [ 50 .. 100 ], x  `mod`   7  ==  3 ]  
[52 , 59 , 66 , 73 , 80 , 87 , 94 ]  

成功!从一个List中筛选出符合特定限制条件的操作也可以称为过滤(flitering)。即取一组数并且按照一定的限制条件过滤它们。再举个例子 吧,假如我们想要一个comprehension,它能够使list中所有大于10的奇数变为“BANG”,小于10的奇数变为“BOOM”,其他则统统 扔掉。方便重用起见,我们将这个comprehension置于一个函数之中。

boomBangs xs  =  if  x  <  10   then   "BOOM!"   else   "BANG!"  |  x  <-  xs, odd x]  

这个comprehension的最后部分就是限制条件,使用odd函数判断是否为奇数:返回True,就是奇数,该List中的元素才被包含。

ghci>  boomBangs [ 7 .. 13 ]  
["BOOM!" , "BOOM!" , "BANG!" , "BANG!" ]  

也可以加多个限制条件。若要达到10到20间所有不等于13,15或19的数,可以这样:

ghci>  [ x  |  x  <-  [ 10 .. 20 ], x  /=  13 , x  /=  15 , x  /=  19 ]  
[10 , 11 , 12 , 14 , 16 , 17 , 18 , 20

除 了多个限制条件之外,从多个List中取元素也是可以的。这样的话comprehension会把所有的元素组合交付给我们的输出函数。在不过滤的前提 下,取自两个长度为4的集合的comprehension会产生一个长度为16的List。假设有两个List,[2,5,10]和[8,10,11], 要取它们所有组合的积,可以这样:

ghci>  [ x*y  |  x  <-  [ 2 , 5 , 10 ], y  <-  [ 8 , 10 , 11 ]]  
[16 , 20 , 22 , 40 , 50 , 55 , 80 , 100 , 110 ]  

意料之中,得到的新List长度为9。若只取乘积为50的结果该如何?

ghci>  [ x*y  |  x  <-  [ 2 , 5 , 10 ], y  <-  [ 8 , 10 , 11 ], x*y  >  50 ]  
[55 , 80 , 100 , 110 ]  

取个包含一组名词和形容词的List comprehension吧,写诗的话也许用得着。

ghci>   let  nouns  =  [ "hobo" , "frog" , "pope" ]  
ghci>   let  adjectives  =  [ "lazy" , "grouchy" , "scheming" ]  
ghci>  [adjective  ++  " "  ++  noun  |  adjective  <-  adjectives, noun  <-  nouns]  
["lazy hobo" , "lazy frog" , "lazy pope" , "grouchy hobo" , "grouchy frog" ,  
"grouchy pope" , "scheming hobo" , "scheming frog" , "scheming pope" ]  

明白!让我们编写自己的length函数吧!就叫做length' !

length' xs  =  sum [ 1  |  _  <-  xs]  

_表示我们并不关心从List中取什么值,与其弄个永远都不回使用的变量,不如直接一个_。这个函数将一个List中所有元素置换为1,并且使其相加求和。得到的结果便是我们的List长度。

友情提示:字符串也是List,完全可以使用list comprehension来处理字符串。如下是个除去字符串中所有非大写字母的函数:

removeNonUppercase st  =  [ c  |  c  <-  st, c  `elem`  [ 'A' .. 'Z' ]]  

测试一下:

ghci>  removeNonUppercase  "Hahaha! Ahahaha!"   
"HA"   
ghci>  removeNonUppercase  "IdontLIKEFROGS"   
"ILIKEFROGS"   

在 这里,限制条件做了所有的工作。它说:只有在['A'..'Z']之间的字符才可以被包含。若操作含有List的List,使用嵌套的List comprehension也是可以的。假设有个包含许多数值的List的List,让我们在不拆开它的前提下除去其中的所有奇数:

ghci>   let  xxs  =  [[ 1 , 3 , 5 , 2 , 3 , 1 , 2 , 4 , 5 ],[ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ],[ 1 , 2 , 4 , 2 , 1 , 6 , 3 , 1 , 3 , 2 , 3 , 6 ]]  
ghci>  [ [ x  |  x  <-  xs, even x ]  |  xs  <-  xxs]  
[[2 , 2 , 4 ],[ 2 , 4 , 6 , 8 ],[ 2 , 4 , 2 , 6 , 2 , 6 ]] 

将List Comprehension分成多行也是可以的。所以若非在GHCI之下,最好还是将List Comprehension分成多行,尤其是需要嵌套的时候。
分享到:
评论

相关推荐

    B10-Haskell趣学指南.pdf

    本文将基于《Haskell趣学指南》一书的目录,详细解析Haskell的各个方面,包括基础语法、类型系统、递归、高阶函数、模块系统、自定义类型和类型类、输入输出处理、函数式编程思维、以及高阶函数等特性。 ### 第一章...

    Haskell趣学指南---文字版.pdf

    在《Haskell趣学指南》这本书中,作者M.Lipovaca提供了学习Haskell的全面指导,从零开始到深入理解函数式编程的高级特性,循序渐进地带读者进入Haskell编程的世界。书中详细介绍了Haskell的语法、数据类型、函数的...

    Haskell趣味学习中文版

    ### Haskell简介与入门指南 **Haskell** 是一种纯函数式编程语言,它不依赖传统的命令式编程模型(如C、C++、Java和Python等),而是采用函数式编程范式。在Haskell中,计算过程是通过数学函数来表达的,变量一旦被...

    t-l-51729-little-red-riding-hood-traditional-tales-differentiated-reading-comprehension-activity.pdf

    t-l-51729-little-red-riding-hood-traditional-tales-differentiated-reading-comprehension-activity.pdf

    Mechanical Comprehension - ASVAB Section Three Mechanical Comprehension题库.docx

    ASVAB( Armed Services Vocational Aptitude Battery)是美国军队入伍资格测试,其中的Mechanical Comprehension部分考察的是考生对机械原理的理解和应用能力。这个部分涉及到杠杆、简单机器、齿轮、摩擦力、压力、...

    Paragraph comprehension - ASVAB Section Eight Paragraph comprehension认证题库.docx

    ASVAB Paragraph Comprehension部分是ASVAB( Armed Services Vocational Aptitude Battery)考试中的一个环节,旨在测试考生理解并推断出书面文本信息的能力。这个认证题库包含了多种类型的阅读理解题目,帮助考生...

    comprehension-exercises-router

    分支机构负责人应按既定的方式执行命令: git branch Mude para分支comprehension-exercises包括git checkout -b comprehension-exercises 。 Énessa branch quevocêrealizaráasoluçãopara oexercício。注意...

    Python进阶内容 List Comprehension _python_

    在Python中,列表推导式(List Comprehension)是处理和构建列表的高级语法,尤其适用于需要对现有列表进行操作或者基于某种条件生成新列表的场景。 列表推导式的语法结构如下: ```python [expression for item in...

    for-comprehension-macgyver

    在研讨会期间,您将学习如何将其与List,Option,Try,Future和Either类型结合使用。 我将介绍标准技术和潜在的陷阱。 滑梯 链接 用于演示文稿/车间或仅有用。 StackOverflows ...

    The Haskell Road to Logic, Maths and Programming

    - **列表(lists)**:介绍列表的基本操作和列表推导(list comprehension)。 #### 六、关系 - **关系(relation)**:定义关系并讨论其属性。 - **实现关系(implementing relations)**:探讨如何使用集合对或特征函数来...

    Reading-Comprehension-Question-Answering-Papers:机器阅读理解调查

    内容 调查/概述论文/文档应阅读机器阅读理解朱凤斌等,“检索与阅读:开放域问答的综合调查” ,arXiv,2021年,论文Mokanarangan Thayaparan,Marco Valentino和AndréFreitas,“机器阅读理解的可解释性调查” ,...

    pythonx学习指南

    - **列表推导式(list comprehension)**:一种更简洁的创建列表的方式,类似于数学上的集合表达式。 #### §1.5 字符串(string) - **字符串的创建与访问**:使用单引号、双引号或三引号来创建字符串,可通过索引和...

    Turkish-Reading-Comprehension-Question-Answering-Dataset:土耳其语阅读理解问答数据集

    ENELPI - 问答系统 我们是谁 ? 您好,我们是三位截至 2020 年毕业于 Adnan Menderes 大学计算机工程系的朋友。 我们的名字分别是 Okan Çiftçi、Uğurcan Kök 和 Filiz Gözet。 自从我们进入该部门以来,我们三...

    SemEval2021-Reading-Comprehension-of-Abstract-Meaning:这是SemEval 2021 Task 4的存储库

    SemEval2021-阅读理解摘要的含义 这是SemEval 2021任务4:对抽象含义的理解的存储库。 它包括用于基准模型和数据的代码。 数据 资料格式 数据以json格式每行存储一个问题。 数据的每个实例都可以作为python ...

    python中lambda函数 list comprehension 和 zip函数使用指南

    lambda 函数 Python 支持一种有趣的语法,它允许你快速定义单行的最小函数。这些叫做 lambda 的函数,是从 Lisp 借用来的,可以用在任何需要函数的地方。 def f(x): return x*2,用lambda函数来替换可以写成:g = ...

    SCP1-040156draft.doc

    CR的目标是将COMPREHENSION-TLV标签从TS 102 223转移到TS 101 220的规范中。COMPREHENSION-TLV标签用于帮助解析和理解在智能卡与终端服务器或网络实体之间的数据传输。 TS 101 220是列出这些标签的规范,而TS 102 ...

    Zero-Shot Cross-Lingual Machine Reading Comprehension via Inter-

    本文主要探讨了零触发跨语言机器阅读理解(Zero-Shot Cross-Lingual Machine Reading Comprehension, ZSLMRC)的任务,这是一种无需在目标语言上进行训练,直接利用源语言知识解决其他语言阅读理解问题的方法。...

    Python-中LIST操作.docx

    9. **列表推导式**(List Comprehension): 这是一种简洁的创建列表的方式,例如`[ &lt;expr1&gt; for k in L if &lt;expr2&gt; ]`,它根据条件`expr2`过滤`L`中的元素并应用表达式`expr1`。 10. **字典(Dictionary)**: ...

Global site tag (gtag.js) - Google Analytics