Where is the mistake in this tail recursive Haskell function? - haskell

I have to implement a sum function in Haskell in two ways. One function with tail recursion and the other without tail recursion.
Here is the one without tail recursion and it works perfectly
sum1 x = if x==0 then 0 else x + sum1(x-1)
Here is my attempt with tail recursion and it doesn't work:
sum2 x = help 0 y
help x y = if y==0 then x else help(x+y,y-1)
Can someone point out the mistake?

Your line:
help x y = if y==0 then x else help(x+y,y-1)
is not the correct syntax for calling a function. Because here the Haskell compiler will interpret it as:
help x y = if y==0 then x else help (x+y,y-1)
-- ^ a tuple
Instead you should write:
help x y = if y==0 then x else help (x+y) (y-1)
-- ^ two arguments
Furthermore you can also use guards, like:
helper x y | y == 0 = x
| otherwise = help (x+y) (y-1)
Finally there is also an error in the first line of sum2. It should be x instead of y:
sum2 x = help 0 x
So in full, we get:
sum2 x = help 0 x
helper s x | x == 0 = s
| otherwise = help (s+x) (x-1)
I also renamed y in the helper to x and x to s (as in sum) to make it less confusing (kudos to #Bergi for commenting on this).
Or use an eta reduction:
sum2 = help 0
Finally note that you do not need recursion for this. An implementation that would work faster is the following:
sum3 x = div (x*(x+1)) 2
Since:
n
---
\ (n+1) n
/ i = -------
--- 2
i=1

Related

whats the advantage of using guards in Haskell?

count_instances :: (Int)->([Int])->Int
count_instances x [] = 0
count_instances x (t:ts)
| x==t = 1+(count_instances x ts)
| otherwise = count_instances x ts
i just want to know whats so good about using guards in this Question ?
A guard can be a way to write only one half of an if-then-else expression; you can omit the else and have a partial function.
-- Leave the function undefined for x /= y
foo x y | x == y = ...
You can do the same with a case statement, but it's more verbose
foo x y = case x == y of
True -> ...
It's also easier to list several unrelated conditions as a set of alternatives than it is with a nested if-then-else or case expressions.
foo x y | p1 x y = ...
foo x y | p2 x y = ...
foo x y | p3 x y = ...
foo x y = ...
vs
foo x y = if p1 x y then ...
else (if p2 x y then ...
else (if p3 x y then ... else ...))
Patterns with guards are probably the most concise way to write code that otherwise would require nested case/if expressions.
Not the least advantage is that a where clause applies to all the guards right hand sides. This is why your example could be even more concise:
count_instances :: (Int)->([Int])->Int
count_instances x [] = 0
count_instances x (t:ts)
| x==t = 1+rest
| otherwise = rest
where rest = count_instances x ts
A guard is haskell's most general conditional statement, like if/then/else in other languages.
Your code shows a straight forward implementation of counting contents of a list equal to a given parameter. This is a good example to learn how haskell's recursion works.
An alternative implementation would be
count_instances :: Int -> [Int] -> Int
count_instances i = length . filter (==i)
that reuses already existing functions from the Prelude module. This is shorter and probably more readable.

Recursive addition in Haskell

The problem:
You are given a function plusOne x = x + 1. Without using any other (+)s, define a recursive function addition such that addition x y adds x and y together.
(from wikibooks.org)
My code (it does not work -- endless loop):
plusOne x = x + 1
addition x y
| x > 0 = addition (plusOne y) (x-1)
| otherwise = y
Questions:
How to connect the plusOne function to the addition recursive function?
How should it be written?
You are mixing up x and y in your recursive case
addition x y | y > 0 = addition (plusOne x) (y - 1) -- x + y == (x + 1) + (y - 1)
| otherwise = x -- x + 0 = x
using == and 0
addition = add 0 where
add a y x | a == y = x
| otherwise = add (plusOne a) y (plusOne x)

Prelude exponentiation is hard to understand

I was reading the Haskell Prelude and finding it pretty understandable, then I stumbled upon the exponention definition:
(^)              :: (Num a, Integral b) => a -> b -> a
x ^ 0            =  1
x ^ n | n > 0    =  f x (n-1) x
where f _ 0 y = y
f x n y = g x n  where
g x n | even n  = g (x*x) (n `quot` 2)
| otherwise = f x (n-1) (x*y)
_ ^ _            = error "Prelude.^: negative exponent"
I do not understand the need for two nested wheres.
What I understood so far:
(^)              :: (Num a, Integral b) => a -> b -> a
The base must be a number and the exponent intege, ok.
x ^ 0            =  1
Base case, easy.
g x n | even n  = g (x*x) (n `quot` 2)
| otherwise = f x (n-1) (x*y)
Exponention by squaring... kind of ... Why is the f helper needed? Why are f and g given single letter names? Is it just optimization, am I missing something obvious?
_ ^ _            = error "Prelude.^: negative exponent"
N > 0 was checked before, N is negative if we arrived here, so error.
My implementation would be a direct translation to code of:
Function exp-by-squaring(x, n )
if n < 0 then return exp-by-squaring(1 / x, - n );
else if n = 0 then return 1; else if n = 1 then return x ;
else if n is even then return exp-by-squaring(x * x, n / 2);
else if n is odd then return x * exp-by-squaring(x * x, (n - 1) / 2).
Pseudocode from wikipedia.
To illustrate what #dfeuer is saying, note that the way f is written it either:
f returns a value
or, f calls itself with new arguments
Hence f is tail recursive and therefore can easily be transformed into a loop.
On the other hand, consider this alternate implementation of exponentiation by squaring:
-- assume n >= 0
exp x 0 = 1
exp x n | even n = exp (x*x) (n `quot` 2)
| otherwise = x * exp x (n-1)
The problem here is that in the otherwise clause the last operation performed is a multiplication. So exp either:
returns 1
calls itself with new arguments
calls itself with some new arguments and multiplies the result by x.
exp is not tail recursive and therefore cannot by transformed into a loop.
f is indeed an optimization. The naive approach would be "top down", calculating x^(n `div` 2) and then squaring the result. The downside of this approach is that it builds a stack of intermediate computations. What f lets this implementation do is to first square x (a single multiplication) and then raise the result to the reduced exponent, tail recursively. The end result is that the function will likely operate entirely in machine registers. g seems to help avoid checking for the end of the loop when the exponent is even, but I'm not really sure if it's a good idea.
As far as I understand it exponentiation is solved by squaring as long as the exponent is even.
This leads to the answer why f is needed in case of an odd number - we use f to return the result in the case of g x 1, in every other odd case we use f to get back in the g-routine.
You can see it best I think if you look at an example:
x ^ n | n > 0 = f x (n-1) x
where f _ 0 y = y
f x n y = g x n
where g x n | even n = g (x*x) (n `quot` 2)
| otherwise = f x (n-1) (x*y)
2^6 = -- x = 2, n = 6, 6 > 0 thus we can use the definition
f 2 (6-1) 2 = f 2 5 2 -- (*)
= g 2 5 -- 5 is odd we are in the "otherwise" branch
= f 2 4 (2*2) -- note that the second '2' is still in scope from (*)
= f 2 4 (4) -- (**) for reasons of better readability evaluate the expressions, be aware that haskell is lazy and wouldn't do that
= g 2 4
= g (2*2) (4 `quot` 2) = g 4 2
= g (4*4) (2 `quot` 2) = g 16 1
= f 16 0 (16*4) -- note that the 4 comes from the line marked with (**)
= f 16 0 64 -- which is the base case for f
= 64
Now to your question of using single letter function names - that's the kind of thing you have to get used to it is a way most people in the community write. It has no effect on the compiler how you name your functions - as long as they start with a lower case letter.
As others noted, the function is written using tail-recursion for efficiency.
However, note that one could remove the innermost where while preserving tail-recursion as follows: instead of
x ^ n | n > 0 = f x (n-1) x
where f _ 0 y = y
f x n y = g x n
where g x n | even n = g (x*x) (n `quot` 2)
| otherwise = f x (n-1) (x*y)
we can use
x ^ n | n > 0 = f x (n-1) x
where f _ 0 y = y
f x n y | even n = f (x*x) (n `quot` 2) y
| otherwise = f x (n-1) (x*y)
which is also arguably more readable.
I have however no idea why the authors of the Prelude chose their variant.

Infinite loop in recursive Haskell function

Hmm... why does this function ends in an infinite loop when evaluating for any integer > 3?
smallestMultiple n = factors [2..n] where
factors [] = []
factors (h:xs) = h:(factors $ filter ((<)1) [div x h|x<-xs])
where
div x y
|x `mod` y ==0 = x `div` y
|otherwise = x
It appears that the main problem is that you define a local version of div:
div x y
| x `mod` y == 0 = x `div` y
| otherwise = x
Since bindings in where clauses (as well as in let) are recursive, the div on the right hand side of the first case refers to the same div you're defining! You can fix this by using a different name, like div':
div' x y
| x `mod` y == 0 = x `div` y
| otherwise = x

Haskell - too few arguments

I want to write a Haskell program that calculates the sum of numbers between 2 given numbers.
I have the following code:
sumInt :: Int -> Int -> Int
sumInt x y
| x > y = 0
| otherwise = x + sumInt x+1 y
But when I compile it I get the following error:
SumInt is applied to too few arguments.
I don't understand what I'm doing wrong. Any ideas?
You need parentheses around x+1:
| otherwise = x + sumInt (x + 1) y
The reason is that function application binds more tightly than operators, so whenever you see
f x <> y
This is always parsed as
(f x) <> y
and never as
f (x <> y)

Resources