Tail recursion vs Primitive Recursion - haskell

I am studying about haskell recursion. and when i read about recursion topic which talk about this two different type of recursion. i am understand how tail recursion works and its step to be done. i am not understand how is primitive recursion done in background. can anyone here help explain more about primitive and given some example ?
For example : tail recursion
sum:: [Int] -> Int
sum [] = 0
sum (x:xs) = x+ (sum xs)
process of sum [1,2,3,4]:
= 1 + sum[2,3,4]
= 1 + (2 + sum [3,4] )
= 1 + ( 2 + ( 3 + sum[4]) )
= 1 + (2 + (3 ( 4 + sum[])))
= 1 + (2 + ( 3 + ( 4 + 0 ) ) )
= 10
How does primitive recursion works?

Intuitively, we have tail recursion when we have a recursive function such that, when a recursive call is performed, the result of that call is the result of the function. In a sense, after the recursive call "there is nothing more to be done".
-- tail recursion
f1 n = if ... then ... else f1 (n - 1)
-- not tail recursion
f2 n = if ... then ... else 5 * f2 (n - 1)
Primitive recursion is another beast. We have primitive recursion when every recursive call is done using an argument which is a "direct subterm" of the original one.
-- primitive recursion (& non-tail recursion)
f1 (x:xs) = g x (f1 xs) -- xs is asubterm of x:xs
-- a tree type
data T = K Int T T
-- primitive recursion (& non-tail recursion)
f2 (K n l r) = h n (f2 l) (f2 r) -- l, r are subterms
-- non-primitive recursion (& tail recursion)
f3 (K n l (K m rl rr)) = f3 (K m (K n rl l) rl) -- not a subterm

Related

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.

Haskell take sum recursively

Hello I want to take a sum of functions call in Haskel but I cannot figure out what I am doing wrong. To be more specific, I have a function f(a,b,c)=a+b+c and I want to take an int like this:
x=Sum( from i=0 to i=c) f(1,1,i)
so far I have written this, but it doesn't even compile. Can you help me?
f a b c = a+b+c
my_sum f a b c+1 =f a b c+1 + my_sum f a b c
I get parse error in pattern my_sum
eg for my_sum f 1 1 5 the result would be f(1,1,5)+f(1,1,4)+f(1,1,3)+f(1,1,2)+f(1,1,1)
I dont want to use lists
n+k patterns are bad
Your code:
my_sum f a b c+1 =f a b c+1 + my_sum f a b c
includes a pattern in the form c+1 which A) should have parentheses B) Needs a base case (I assume you want to stop when c == 0) and C) is a syntactic form that has been removed from the language.
Instead, explicitly subtract 1 from c when you want and be sure to handle the base case:
my_sum f a b 0 = f a b 0
my_sum f a b n = f a b n + my_sum f a b (n-1)
This also has a memory leak meaning it will build up a large computation in the form f1 + (f a b n' + (f a b n'' + (f a b n''' + (.... You can handle the leak by using an accumulator or a higher level function and optimization at compile-time.
A cleaner Solution
List comprehension strikes me as the most reasonable solution here:
sum [f a b i | i <- [0..c] ]
The sum of the function f applied to arugments a, b and finally i where i ranges from 0 to c inclusively.
You can't have the c+1 on the left side of a definition. Since you're just summing, it doesn't matter if you count up from 0 to c or count down from c to 0, so you could instead do
my_sum f a b 0 = f a b 0
my_sum f a b c = f a b c + my_sum f a b (c - 1)
Then you could use it as
> let g x y z = x + y + z
> my_sum g 0 0 10
55
Some more detail on why your code failed to compile: Whenever you have a pattern on the left side of a definition, such as
fib 0 = 1
fib 1 = 1
fib n = fib (n - 1) + fib (n - 2)
You can only match on constructors, names (like n or c), and literals (which are essentially constructors for the basic types). The function + is not a constructor, it is a function belonging to the Num typeclass, so therefore you can not pattern match on it. You may be confused from seeing list pattern matching before because it uses an operator:
myListSum [] = 0
myListSum (x:xs) = x + myListSum xs
but in fact, : is the Cons constructor for lists, and [] is the empty list constructor. You can think of the list type defined as
data [a] = [] | a : [a]
Or, if you were to replace all the symbols with words
data List a = Empty | Cons a (List a)
although its a bit different in reality since there's more that goes into defining lists, but that's the basic idea. This means that a pattern like
f [] = ...
f (x:xs) = ...
Is equivalent to
f Empty = ...
f (Cons x xs) = ...
just with more convenient syntax.
However, Int can be though of as a very large ADT defined as
data Int = -2147483648 | -2147483647 | ... | -1 | 0 | 1 | ... | 2147483646 | 2147483647
where each number itself is a different constructor. Then you can match on any individual number, but not anything like (x + 1) or (x * 2), because + and * are not constructors, just regular functions. (Note: Int is not actually defined this way because that would be really inefficient, it's defined at a more primitive level)
You can get from list formulations to the non-list, recursive formulations, with manual inlining and fusing of the functions in play:
{-# LANGUAGE BangPatterns #-}
import Data.List
f a b c = a+b+c
g f a b c = sum . map (f a b) $ [0..c]
= foldl' (\ !x y -> x + f a b y) 0 $ enumFromTo 0 c
= h 0 0 where
h !acc i | i > c = acc
| otherwise = h (acc + f a b i) (i+1)
Strictness annotations prevent uncontrolled build-up of thunks and stack overflow for big values of c.

Recursion confusion in Haskell

I hope someone can help figure out where my error lies. Calling g 3 4 0 2 (M.empty,0) [], I would expect [[2,1,0,1]] as a result. Instead, I'm seeing [[2,1,0,1],[2,1,0,1]].
The program is supposed to accumulate distinct digit patterns of length m by adding a different digit to the list each time, returning back down when reaching n-1 and up when reaching 0. The apparent problem happens in the middle when the function is called recursively for both the up and down directions.
If I comment out line 11 like so:
else g n m (digitCount + 1) (lastDigit + 1) (hash',hashCount') (lastDigit:digits)
-- g n m (digitCount + 1) (lastDigit - 1) (hash',hashCount') (lastDigit:digits)
I get the correct result []
As when commenting out line 11 and modifying line 10 to:
else g n m (digitCount + 1) (lastDigit - 1) (hash',hashCount') (lastDigit:digits)
Again, a correct result [[2,1,0,1]]
Why when calling g twice using the ++ operator, I'm getting two [2,1,0,1]'s instead of just one? In my thinking, each result in g should be distinct because in any recursive call, a different order of digits is (or should be) accumulating.
Thanks in advance.
import qualified Data.Map as M
g :: Int -> Int -> Int -> Int -> (M.Map Int Bool, Int) -> [Int] -> [[Int]]
g n m digitCount lastDigit (hash,hashCount) digits
| digitCount == m = if test then [reverse digits] else []
| otherwise =
if lastDigit == 0
then g n m (digitCount + 1) (lastDigit + 1) (hash',hashCount') (lastDigit:digits)
else if lastDigit == n - 1
then g n m (digitCount + 1) (lastDigit - 1) (hash',hashCount') (lastDigit:digits)
else g n m (digitCount + 1) (lastDigit + 1) (hash',hashCount') (lastDigit:digits)
++ g n m (digitCount + 1) (lastDigit - 1) (hash',hashCount') (lastDigit:digits)
where test = hashCount == n
(hash',hashCount') =
if test
then (M.empty,hashCount)
else case M.lookup lastDigit hash of
Just anyting -> (hash,hashCount)
Nothing -> (M.insert lastDigit True hash,hashCount + 1)
Now that you've got it working, here's a more generic approach.
We need to walk the tree of solutions.
data S a = Solution a | Explore [S a]
Solutions are leaves of this tree, Explore are lists of options to explore.
-- this is very much unfoldr-like
generator :: [S a] -> [a]
generator [] = []
generator (Solution a: ss) = a: generator ss
generator (Explore ps: ss) = generator $ ss ++ ps
Now, given a list of "maybe-solutions", produce a list of solutions. The generator pattern-matches Explores, and appends the list of solutions to explore to the end of the list. This way we are exploring the solutions breadth-first, and that way we can deal with non-terminating branches. (Depth-first can't get out of non-terminating branches). This of course is at expense of memory, but you can find a finite number of solutions even for problems with infinite number of solutions.
Now, the function that generates solutions for your problem:
g :: Int -> Int -> [S [Int]]
g n m = [Explore $ g' [i] (S.singleton i) | i <- [1..n-1]] where
g' is#(h:_) ms
| h < 0 || h >= n || length is > m = [] --no solution, nothing to explore
| otherwise = maybeSolution ++
[ Explore $ g' ((h-1):is) $ S.insert (h-1) ms
, Explore $ g' ((h+1):is) $ S.insert (h+1) ms ]
where
maybeSolution
| S.size ms == n = [Solution is]
| otherwise = []
Given n and m, produces a list of subtrees to Explore. g' is the helper function that produces a list of subtrees, given a list of Int already produced and a Set of Int already used. So, there is a definite termination condition: we appended a number outside the needed range, or the list became too long - exploring any further cannot produce Solutions, so return []. Otherwise, we are within bounds, maybeSolution sees if the list of Ints is already a valid solution, and suggests more subtrees to explore.
main = print $ map reverse $ generator $ g 3 6
Your problem solved.
Why when calling g twice using the ++ operator, I'm getting two [2,1,0,1]'s instead of just
one? In my thinking, each result in g should be distinct because in any recursive call, a
different order of digits is (or should be) accumulating.
But your pair of (Map,Int) is the same in both calls, so the recursive calls don't know what has been found by the other call. Consider the call g ... (lastDigit-1). It will also call g ... (lastDigit) (by adding 1 to (lastDigit-1) that it got), and follow the branch g ... (lastDigit+1) to produce the same result.
Also, (Map a ()) is a (Set a), and since you don't use the Bool value from the map, it is the same as ():
import qualified Data.Set as S
g :: Int -> Int -> Int -> Int -> (S.Set Int, Int) -> [Int] -> [[Int]]
g n m digitCount lastDigit (hash,hashCount) digits
| digitCount == m = if test then [reverse digits] else []
| lastDigit < 0 || lastDigit == n = []
| otherwise = g n m d' (lastDigit + 1) h' (lastDigit:digits)
++ g n m d' (lastDigit - 1) h' (lastDigit:digits)
where test = hashCount == n
d' = digitCount + 1
h'
| test = (S.empty,hashCount)
| S.member lastDigit hash = (hash,hashCount)
| otherwise = (S.insert lastDigit hash,hashCount + 1)
In your two recursive calls to g combined with (++) in the final else branch, you are passing exactly the same parameters except for lastDigit.
The base case of your recursion doesn't look at lastDigit - it just compares m and digitCount, n and hashCount and then returns [reverse digits].
So in any situation where the (++) case is hit immediately followed by the base case returning [reverse digits], you'll get the same value repeated.
I didn't fully understand your problem specification but perhaps you need to add the "new" value for lastDigit to digits when you make the recursive calls - i.e. (lastDigit-1):digits or (lastDigit+1):digits.

Fibonacci's Closed-form expression in Haskell

How would the Fibonacci's closed form code look like in haskell?
Here's a straightforward translation of the formula to Haskell:
fib n = round $ (phi^n - (1 - phi)^n) / sqrt 5
where phi = (1 + sqrt 5) / 2
This gives correct values only up to n = 75, because it uses Double precision floating-point arithmetic.
However, we can avoid floating-point arithmetic by working with numbers of the form a + b * sqrt 5! Let's make a data type for them:
data Ext = Ext !Integer !Integer
deriving (Eq, Show)
instance Num Ext where
fromInteger a = Ext a 0
negate (Ext a b) = Ext (-a) (-b)
(Ext a b) + (Ext c d) = Ext (a+c) (b+d)
(Ext a b) * (Ext c d) = Ext (a*c + 5*b*d) (a*d + b*c) -- easy to work out on paper
-- remaining instance methods are not needed
We get exponentiation for free since it is implemented in terms of the Num methods. Now, we have to rearrange the formula slightly to use this.
fib n = divide $ twoPhi^n - (2-twoPhi)^n
where twoPhi = Ext 1 1
divide (Ext 0 b) = b `div` 2^n -- effectively divides by 2^n * sqrt 5
This gives an exact answer.
Daniel Fischer points out that we can use the formula phi^n = fib(n-1) + fib(n)*phi and work with numbers of the form a + b * phi (i.e. ℤ[φ]). This avoids the clumsy division step, and uses only one exponentiation. This gives a much nicer implementation:
data ZPhi = ZPhi !Integer !Integer
deriving (Eq, Show)
instance Num ZPhi where
fromInteger n = ZPhi n 0
negate (ZPhi a b) = ZPhi (-a) (-b)
(ZPhi a b) + (ZPhi c d) = ZPhi (a+c) (b+d)
(ZPhi a b) * (ZPhi c d) = ZPhi (a*c+b*d) (a*d+b*c+b*d)
fib n = let ZPhi _ x = phi^n in x
where phi = ZPhi 0 1
Trivially, Binet's formula, from the Haskell wiki page is given in Haskell as:
fib n = round $ phi ^ n / sq5
where
sq5 = sqrt 5
phi = (1 + sq5) / 2
Which includes sharing of the result of the square root. For example:
*Main> fib 1000
4346655768693891486263750038675
5014010958388901725051132915256
4761122929200525397202952340604
5745805780073202508613097599871
6977051839168242483814062805283
3118210513272735180508820756626
59534523370463746326528
For arbitrary integers, you'll need to be a bit more careful about the conversion to floating point values.
Note that Binet's value differs from the recursive formula by quite a bit at this point:
*Main> let fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
*Main> fibs !! 1000
4346655768693745643568852767504
0625802564660517371780402481729
0895365554179490518904038798400
7925516929592259308032263477520
9689623239873322471161642996440
9065331879382989696499285160037
04476137795166849228875
You may need more precision :-)

Comparing 3 output lists in haskell

I am doing another Project Euler problem and I need to find when the result of these 3 lists is equal (we are given 40755 as the first time they are equal, I need to find the next:
hexag n = [ n*(2*n-1) | n <- [40755..]]
penta n = [ n*(3*n-1)/2 | n <- [40755..]]
trian n = [ n*(n+1)/2 | n <- [40755..]]
I tried adding in the other lists as predicates of the first list, but that didn't work:
hexag n = [ n*(2*n-1) | n <- [40755..], penta n == n, trian n == n]
I am stuck as to where to to go from here.
I tried graphing the function and even calculus but to no avail, so I must resort to a Haskell solution.
Your functions are weird. They get n and then ignore it?
You also have a confusion between function's inputs and outputs. The 40755th hexagonal number is 3321899295, not 40755.
If you really want a spoiler to the problem (but doesn't that miss the point?):
binarySearch :: Integral a => (a -> Bool) -> a -> a -> a
binarySearch func low high
| low == high = low
| func mid = search low mid
| otherwise = search (mid + 1) high
where
search = binarySearch func
mid = (low+high) `div` 2
infiniteBinarySearch :: Integral a => (a -> Bool) -> a
infiniteBinarySearch func =
binarySearch func ((lim+1) `div` 2) lim
where
lim = head . filter func . lims $ 0
lims x = x:lims (2*x+1)
inIncreasingSerie :: (Ord a, Integral i) => (i -> a) -> a -> Bool
inIncreasingSerie func val =
val == func (infiniteBinarySearch ((>= val) . func))
figureNum :: Integer -> Integer -> Integer
figureNum shape index = (index*((shape-2)*index+4-shape)) `div` 2
main :: IO ()
main =
print . head . filter r $ map (figureNum 6) [144..]
where
r x = inIncreasingSerie (figureNum 5) x && inIncreasingSerie (figureNum 3) x
Here's a simple, direct answer to exactly the question you gave:
*Main> take 1 $ filter (\(x,y,z) -> (x == y) && (y == z)) $ zip3 [1,2,3] [4,2,6] [8,2,9]
[(2,2,2)]
Of course, yairchu's answer might be more useful in actually solving the Euler question :)
There's at least a couple ways you can do this.
You could look at the first item, and compare the rest of the items to it:
Prelude> (\x -> all (== (head x)) $ tail x) [ [1,2,3], [1,2,3], [4,5,6] ]
False
Prelude> (\x -> all (== (head x)) $ tail x) [ [1,2,3], [1,2,3], [1,2,3] ]
True
Or you could make an explicitly recursive function similar to the previous:
-- test.hs
f [] = True
f (x:xs) = f' x xs where
f' orig (y:ys) = if orig == y then f' orig ys else False
f' _ [] = True
Prelude> :l test.hs
[1 of 1] Compiling Main ( test.hs, interpreted )
Ok, modules loaded: Main.
*Main> f [ [1,2,3], [1,2,3], [1,2,3] ]
True
*Main> f [ [1,2,3], [1,2,3], [4,5,6] ]
False
You could also do a takeWhile and compare the length of the returned list, but that would be neither efficient nor typically Haskell.
Oops, just saw that didn't answer your question at all. Marking this as CW in case anyone stumbles upon your question via Google.
The easiest way is to respecify your problem slightly
Rather than deal with three lists (note the removal of the superfluous n argument):
hexag = [ n*(2*n-1) | n <- [40755..]]
penta = [ n*(3*n-1)/2 | n <- [40755..]]
trian = [ n*(n+1)/2 | n <- [40755..]]
You could, for instance generate one list:
matches :: [Int]
matches = matches' 40755
matches' :: Int -> [Int]
matches' n
| hex == pen && pen == tri = n : matches (n + 1)
| otherwise = matches (n + 1) where
hex = n*(2*n-1)
pen = n*(3*n-1)/2
tri = n*(n+1)/2
Now, you could then try to optimize this for performance by noticing recurrences. For instance when computing the next match at (n + 1):
(n+1)*(n+2)/2 - n*(n+1)/2 = n + 1
so you could just add (n + 1) to the previous tri to obtain the new tri value.
Similar algebraic simplifications can be applied to the other two functions, and you can carry all of them in accumulating parameters to the function matches'.
That said, there are more efficient ways to tackle this problem.

Resources