Explain how a recursive Haskell list function works?
I know what the following function does I would just like an explanation of how it works and the calculations that take place:
sponge :: Int -> [a] -> [a]
sponge 0 开发者_StackOverflow社区xs = xs
sponge n [] = []
sponge n (x:xs) = sponge (n-1) xs
I just seem to have lost the plot with it all now :(
Any help to get me back on track would be much appreciated! :)
It's a recursive function over two variables. You can break it apart line-by-line to understand it:
sponge :: Int -> [a] -> [a]
Two arguments, one an Int
, one a list of some elements.
sponge 0 xs = xs
The base case. If the Int
argument is zero, just return the list argument unmodified.
sponge n [] = []
Another base case, if the list is empty, immediately return the empty list.
sponge n (x:xs) = sponge (n-1) xs
Finally, the inductive step. If the list is non-empty (i.e. made up of at least one element and a tail, denoted by x:xs
), then the result is sponge
called on n-1
and the tail of the list.
So what will this function do? It will return the tail of the list after dropping n
elements. It is the same as the drop
function:
> drop 10 [1..20]
[11,12,13,14,15,16,17,18,19,20]
And
> sponge 10 [1..20]
[11,12,13,14,15,16,17,18,19,20]
In fact, we can ask QuickCheck to confirm:
> quickCheck $ \n xs -> sponge n xs == drop n xs
*** Failed! Falsifiable (after 7 tests and 5 shrinks):
-1
[()]
Ah! They're different. When n
is negative! So we can modify the property relating the two functions:
> quickCheck $ \n xs -> n >= 0 ==> sponge n xs == drop n xs
+++ OK, passed 100 tests.
So your function behaves like drop, for cases when n
is positive.
Here's a trace of the intermediate values of n
and xs
, obtained via the hood debugger:
It takes two parameters, as you can see: an Int and a list. It pattern-matches to distinguish three cases: 1) the Int is zero; 2) the list is empty; or, 3) the Int is not zero nor is the list empty.
In case 1 it returns the list; in case 2, it returns the empty list (which is what the second parameter was anyway); in case 3, it recursively calls itself with original Int parameter minus 1 and the original list minus its first element.
It looks a lot like "drop" from the Prelude.
精彩评论