Haskell List理解创建功能

时间:2013-01-30 01:20:50

标签: haskell

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

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

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

类似的东西:

Prelude>subtractOne(x)

4 个答案:

答案 0 :(得分:13)

(您可以将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,并且对于每项权力,我们从x获取所有xs,并计算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。)

答案 1 :(得分:8)

您可以使用map功能执行此操作:

subtractOne = map (subtract 1)

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

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

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

答案 2 :(得分:2)

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

subtractOne [] = []

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

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

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

答案 3 :(得分:1)

map (subtract 1) x将有效。

subtractOne = map (subtract 1) 

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