2011-06-12 29 views
0

我知道下面的功能是什么我只是想它是如何工作的解释和所发生的计算:解释递归Haskell列表函数是如何工作的?

sponge :: Int -> [a] -> [a] 
sponge 0 xs = xs 
sponge n [] = [] 
sponge n (x:xs) = sponge (n-1) xs 

我似乎失去了它所有的情节现在:(

任何帮助让我回到正轨上:) :)

+0

你说你已经失去的情节,并偏离了轨道,但你给任何线索到什么你不明白。这很重要,因为这段代码只需要对Haskell非常基本的理解。那么这里有没有你不明白的语法? – 2011-06-13 01:19:57

+0

这个问题是以误导的方式编辑的。通过添加OP没有使用的“递归”一词,它给人留下这样的印象:OP是有问题的递归,但是我们不知道OP在递归方面有问题......甚至OP知道递归是或知道函数是递归的。 – 2011-06-13 01:24:26

+0

@Jim Balter添加了词递归,所以我们可以稍后找到答案,按照适当的条件分类。像“解释这个功能”这样的标题是不可搜索的。 – 2011-06-17 17:22:44

回答

17

它是两个变量的递归函数。你可以打破它除了行由行去理解它:

sponge :: Int -> [a] -> [a] 

两个参数,一个一个Int,一个有些元素的列表。

sponge 0 xs = xs 

基本情况。如果Int参数为零,则只返回未修改的列表参数。

sponge n [] = []  

另一个基本情况,如果列表为空,立即返回空列表。

sponge n (x:xs) = sponge (n-1) xs 

最后,归纳步骤。如果列表是非空的(即,由至少一个元素和尾部组成,由x:xs表示),则结果是在n-1上调用的sponge和列表的尾部。

那么这个函数会做什么?它会在删除n元素后返回列表的尾部。这是一样的drop功能:

> drop 10 [1..20] 
[11,12,13,14,15,16,17,18,19,20] 

而且

> sponge 10 [1..20] 
[11,12,13,14,15,16,17,18,19,20] 

事实上,我们可以要求快速检查,以确认:

> quickCheck $ \n xs -> sponge n xs == drop n xs 
*** Failed! Falsifiable (after 7 tests and 5 shrinks):  
-1 
[()] 

啊!他们不同。当n为负数!因此,我们可以修改属性与这两个功能:

> quickCheck $ \n xs -> n >= 0 ==> sponge n xs == drop n xs 
+++ OK, passed 100 tests. 

所以你的函数的行为就像一滴水,因为情况下,当n为正。


这里是nxs中间值的痕迹,通过hood debugger获得:

enter image description here

2

它需要两个参数,你可以看到:一个Int和一个列表。它通过模式匹配来区分三种情况:1)Int为零; 2)列表为空;或者3)Int不为零,列表也不为空。

在情况1中它返回列表;在情况2中,它返回空列表(反正是第二个参数);在情况3中,它递归地用原始Int参数减去1和原始列表减去它的第一个元素

它看起来很像前奏曲中的“drop”。