繁体   English   中英

Haskell List理解创建功能

[英]Haskell List Comprehension creating function

我是Haskell的新手,正在努力学习基础知识。 我很难理解如何操作列表的内容。

假设我有以下列表,我想创建一个函数从列表中的每个元素中减去1,我可以简单地将x传递给函数,这将如何完成?

Prelude>let x = 1:2:3:4:5:[]

就像是:

Prelude>subtractOne(x)

(您可以将1:2:3:4:5:[]更简单地写为[1,2,3,4,5]或甚至[1..5] 。)

推导

你想使用列表推导,所以这里是:

subtractOne xs = [ x-1 | x <- xs ]

在这里,我使用xs代表列表,我从中减去一个。

首先要注意的是x <- xs ,你可以读作“ x取自xs ”。 这意味着我们将依次取xs中的每个数字,每次我们将数字x调用。

x-1是我们为每个x计算和返回的值。

对于更多示例,这里是为每个元素添加一个[x+1|x<-xs]或将每个元素[x*x|x<-xs]平方。

不止一个清单

让我们进一步了解列表理解,编写一个函数,找到正方形,然后是我们给它的数字的立方体,所以

> squaresAndCubes [1..5]
[1,4,9,16,25,1,8,27,64,125]

我们需要

squaresAndCubes xs = [x^p | p <- [2,3], x <- xs]

这意味着我们将幂p取为2然后是3,并且对于每个幂,我们从xs获取所有x s,并将x计算为幂px^p )。

如果我们以相反的方式做到这一点会发生什么?

squaresAndCubesTogether xs = = [x^p | x <- xs, p <- [2,3]]

我们得到了

> squaresAndCubesTogether [1..5]
[1,1,4,8,9,27,16,64,25,125]

它取每个x ,然后直接给你两个权力。

结论 - <-位的顺序告诉您输出的顺序。

过滤

如果我们想只允许一些答案怎么办?

哪个2到100之间的数字可以写成x^y

> [x^y|x<-[2..100],y<-[2..100],x^y<100]
[4,8,16,32,64,9,27,81,16,64,25,36,49,64,81]

这里我们允许所有x和所有y ,只要x^y<100


既然我们对每个元素做了完全相同的事情,我会在实践中使用map写这个:

takeOne xs = map (subtract 1) xs

或更短的

takeOne = map (subtract 1)

(我必须称之为subtract 1因为- 1将被解析为负1.)

您可以使用map函数执行此操作:

subtractOne = map (subtract 1)

List Comprehensions的替代解决方案有点冗长:

subtractOne xs = [ x - 1 | x <- xs ]

为清晰起见,您可能还需要添加类型注释。

您可以使用map功能轻松完成此操作,但我怀疑您想将自己作为学习练习。 在Haskell中执行此操作的一种方法是使用递归。 这意味着你需要将函数分解为两种情况。 第一种情况通常是最简单的输入的基本情况。 对于列表,这是一个空列表[] 从空列表的所有元素中减去一个的结果显然是一个空列表。 在Haskell:

subtractOne [] = []

现在我们需要考虑稍微复杂的递归情况。 对于空列表之外的任何列表,我们可以查看输入列表的头部和尾部。 我们将从头部中减去一个,然后将subtractOne应用于列表的其余部分。 然后我们需要将结果连接在一起以形成新列表。 在代码中,这看起来像这样:

subtractOne (x:xs) = (x - 1) : subtractOne xs

正如我之前提到的,你也可以用map做到这一点。 事实上,它只是一条线和首选的Haskellism。 另一方面,我认为编写自己的函数是一个非常好的主意,这些函数使用显式递归来理解它是如何工作的。 最终,您甚至可能希望编写自己的map功能以进行进一步练习。

map (subtract 1) x将起作用。

subtractOne = map (subtract 1) 

map函数允许您将函数应用于列表的每个元素。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM