递归函数内的枚举计数

时间:2015-09-08 11:22:45

标签: haskell recursion

我想要做类似的事情:

>enumerate ["banana", "potato", "ice"]
[(1, "banana"), (2, "potato"), (3, "ice")]

我写道:

enumerate :: [String] -> [(Int, String)]
enumerate [] = []

我如何控制/管理int计数器?没有支持功能,有没有办法做到这一点?

更新:我了解Zip功能。但是对于学习问题,我想实现自己的zip功能。

更新2:目前代码

这是我到目前为止所做的,使用支持功能。考虑到:

1)我想实现自己的zip功能;
2)我不想改变函数struct:

   enumerate :: [String] -> [(Int, String)]  

enumerate :: [String]->[(Int,String)]
enumerate [] = []
enumerate list = aux 1 list


aux :: Int->[String]->[(Int, String)]
aux _ [] = []
aux i (x:xs) = [(i, x)] ++ aux (i+1) xs

是否可以改善此功能?因为我不想再添加一个函数,所以我认为支持函数是唯一的方法,对吧?

3 个答案:

答案 0 :(得分:5)

不要害怕写一个支持函数,实际上,把它视为机会:为什么任意起始值为1?为什么没有功能

>enumerateFrom 42 ["banana", "potato", "ice"]
[(42, "banana"), (43, "potato"), (44, "ice")]

完成后,enumerate很容易。

修改的: 要么给你的aux函数一个真实的名字,恕我直言enumerateFrom是好的,或者如果你已经知道那么将它移到where子句中。听听chi,使用x : ...代替[x] ++ ...

答案 1 :(得分:1)

已经有一个名为zipzip :: [a] -> [b] -> [(a,b)])的函数。现在,对于您的函数,您只需传递一个以1,2,...作为第一个参数的列表并获得结果,例如。

enumerate :: [String] -> [(Int, String)]
enumerate = zip [1..]

修改

如果您还想实现自己的zip功能,请使用:

zip' :: [a] -> [b] -> [(a,b)]
zip' _ [] = []
zip' [] _ = []
zip' (x:xs) (y:ys) = (x,y):zip' xs ys

您选择两个列表([a][b])并将每个元素放入元组中。边缘情况是核心,当其中一个列表为空时,您返回一个空列表。否则,您使用模式匹配来获取列表的第一个元素,将它们放入元组中,并使用列表的尾部再次调用zip'

答案 2 :(得分:0)

当您澄清时,您想要实现自己的zip:

$("[data-collapse-group]").on('show.bs.collapse', function () {
  var $this = $(this);
  var thisCollapseAttr = $this.attr('data-collapse-group');
  $("[data-collapse-group='" + thisCollapseAttr + "']").not($this).collapse('hide');
});