解释递归Haskell列表函数如何工作?

时间:2011-06-12 15:55:24

标签: list haskell recursion

我知道以下功能是什么,我只想解释它是如何工作的以及发生的计算:

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

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

任何让我重回正轨的帮助都会非常感激! :)

2 个答案:

答案 0 :(得分:17)

这是两个变量的递归函数。您可以逐行拆分以理解它:

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

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

sponge 0 xs = xs

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

sponge n [] = []    

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

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

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

那么这个功能会做什么?在删除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确认:

> 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为正的情况,您的函数就像drop一样。


以下是通过hood debugger获得的nxs的中间值的跟踪:

enter image description here

答案 1 :(得分:2)

它可以看到两个参数,如您所见:Int和列表。它模式匹配以区分三种情况:1)Int为零; 2)清单是空的;或者,3)Int不为零,列表也不为空。

在案例1中,它返回列表;在情况2中,它返回空列表(这是第二个参数无论如何);在第3种情况下,它以原始Int参数减1 递归调用自身,原始列表减去其第一个元素

它看起来很像Prelude中的“掉落”。