我是Haskell的新手,正在努力学习基础知识。我很难理解如何操纵列表的内容。
假设我有以下列表,我想创建一个函数从列表中的每个元素中减去1,我可以简单地将x传递给函数,这将如何完成?
Prelude>let x = 1:2:3:4:5:[]
类似的东西:
Prelude>subtractOne(x)
答案 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
到权力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。)
答案 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
函数允许您将函数应用于列表的每个元素。