Thomas Davie tom.davie at gmail.com
Wed Mar 18 04:28:52 EDT 2009

```On 18 Mar 2009, at 08:36, The_Polymorph at rocketmail.com wrote:

>
>
> Thanks for the explanations. Could we perhaps examine one recursive
> example in detail, i.e., step-by-step, as I'm still confused? Maybe
> the following program from chapter 2 of
>
> myDrop n xs = if n <= 0 || null xs
>               then xs
>               else myDrop (n - 1) (tail xs)

In this example, I'm gonna use the "~>" symbol to mean "reduces to",
that is, if you perform one more evaluation step, you get this.  We're
going to try and evaluate myDrop 2 [1,2,3,4]

myDrop 2 [1,2,3,4]
{ Reduce myDrop 2 [1,2,3,4] to its right hand side as defined
above }
~> if 2 <= 0 || null [1,2,3,4] then [1,2,3,4] else myDrop (2-1) (tail
[1,2,3,4])
{ Reduce 2 <= 0 to False }
~> if False || null [1,2,3,4] then [1,2,3,4] else myDrop (2-1) (tail
[1,2,3,4])
{ Reduce null [1,2,3,4] to False
~> if False || False then [1,2,3,4] else myDrop (2-1) (tail [1,2,3,4])
{ Reduce False || False to False }
~> if False then [1,2,3,4] else myDrop (2-1) (tail [1,2,3,4])
{ Reduce the if expression to its else branch }}
~> myDrop (2-1) (tail [1,2,3,4])
{Reduce myDrop (2-1) (tail [1,2,3,4]) to its right hand side as
defined above }
~> if n <= 0 || null xs then xs else myDrop (n - 1) (tail xs) where n
= (2-1); xs = tail [1,2,3,4]
{ Reduce 2 - 1 to 1 }
~> if n <= 0 || null xs then xs else myDrop (n - 1) (tail xs) where n
= 1; xs = tail [1,2,3,4]
{ Reduce 1 <= 0 to False }
~> if False || null xs then xs else myDrop (n - 1) (tail xs) where n =
1; xs = tail [1,2,3,4]
{ Remove superfluous definition of n (there's only one use of it
now) }
~> if False || null xs then xs else myDrop (1 - 1) (tail xs) where xs
= tail [1,2,3,4]
{ Reduce tail [1,2,3,4] to [2,3,4] }
~> if False || null xs then xs else myDrop (1 - 1) (tail xs) where xs
= [2,3,4]
{ Reduce null [2,3,4] to False }
~> if False || False then xs else myDrop (1 - 1) (tail xs) where xs =
[2,3,4]
{ Reduce False || False to False }
~> if False then xs else myDrop (1 - 1) (tail xs) where xs = [2,3,4]
{ Reduce if expression to its else branch }
~> myDrop (1 - 1) (tail xs) where xs = [2,3,4]
{ Remove superfluous definition of xs as there's only one use of
it now }
~> myDrop (1 - 1) (tail [2,3,4])
{ Reduce myDrop (1 - 1) (tail [2,3,4]) to its right hand side as
defined above }
~> if n <= 0 || null xs then xs else myDrop (n - 1) (tail xs) where n
= (1 - 1); xs = tail [2,3,4]
{ Reduce 1 - 1 to 0 }
~> if n <= 0 || null xs then xs else myDrop (n - 1) (tail xs) where n
= 0; xs = tail [2,3,4]
{ Reduce 0 <= 0 to True }
~> if True || null xs then xs else myDrop (n - 1) (tail xs) where n =
0; xs = tail [2,3,4]
{ Remove superfluous definition of n, as its only used in one
place now }
~> if True || null xs then xs else myDrop (0 - 1) (tail xs) where xs =
tail [2,3,4]
{ Reduce True || anything to True }
~> if True then xs else myDrop (0 - 1) (tail xs) where xs = tail [2,3,4]
{ Reduce if expression to its then branch }
~> xs where xs = tail [2,3,4]
{ Remove superfluous definition of xs, as it only appears once }
~> tail [2,3,4]
{ Reduce tail [2,3,4] to [3,4] }
~> [3,4]

Hope that helps

Bob
```