[英]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
计算为幂p
( x^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.