forked from noelmarkham/learn-you-a-haskell-exercises
-
Notifications
You must be signed in to change notification settings - Fork 0
/
5-recursion.hs
66 lines (58 loc) · 2.68 KB
/
5-recursion.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
-- Raise x to the power y, using recursion
-- For example, power 5 2 = 25
power :: Int -> Int -> Int
power x 0 = 1
power x y = x * power x (y - 1)
-- create a list of length n of the fibbonaci sequence in reverse order
-- examples: fib 0 = [0]
-- fib 1 = [1, 0]
-- fib 10 = [55,34,21,13,8,5,3,2,1,1,0]
-- try to use a where clause
fib :: (Num a, Eq a) => a -> [a]
fib 0 = [0]
fib 1 = [1, 0]
fib x = (a + b) : l
where l@(a:b:t) = fib (x - 1)
-- This is not recursive, but have a go anyway.
-- Create a function which takes two parameters, a number and a step
-- The result is the sign of the original number reversed, and the step added to the absolute value
-- Confused? Some examples: stepReverseSign 6 2 = -8
-- stepReverseSign -3 1 = 4
-- stepReverseSign 1 2 = -3
stepReverseSign :: (Fractional a, Ord a) => a -> a -> a
stepReverseSign a
| a < 0 = (+) (abs a)
| otherwise = (-) (-a)
{- Lets calculate pi.
- The Leibniz formula for pi (http://en.wikipedia.org/wiki/Leibniz_formula_for_%CF%80)
- Can be defined as pi = (4/1) - (4/3) + (4/5) - (4/7) ....
- We can create a function, where given a certain tolerance, we can recursively calculate
- Pi to within that tolerance.
- Lets create two functions, piCalc, and piCalc', the latter we will recursively call
- until our pi calculation is within the tolerance
- The piCalc function is defined as:
- piCalc :: (Fractional a, Integral b, Ord a) => a -> (a, b)
- Given a tolerance, say, 0.001, it will return a tuple.
- fst is pi to an accuracy of the tolerance, 0.001 in this case
- snd is the number of recursive steps taken to calculate it, after all this chapter is about recursion!
- Example: piCalc 0.001 = (3.1420924036835256,2000)
- The piCalc' function is defined as
- piCalc' :: (Ord a, Fractional a, Integral b) => a -> a -> a -> b -> (a, b)
- Lots of parameters!
- The first parameter is the current denominator from the Leibniz formula
- The next is our calculation of pi from our previous attempt
- The next is the tolerance
- The final parameter is the number of times this function has been called (ie, we add one every time we recurse
- Example piCalc' 1 0.0 0.001 0 = (3.1420924036835256,2000)
-
- Feel free to change the parameter order, what parameters you need etc in order to get this to work for you,
- But, of course the output of piCalc should remain as (pi, count)
-
- You may find the stepReverseSign function handy
-}
piCalc :: (Fractional a, Integral b, Ord a) => a -> (a, b)
piCalc a = piCalc' 1 0 a 0
piCalc' :: (Ord a, Fractional a, Integral b) => a -> a -> a -> b -> (a, b)
piCalc' w x y z
| 4 / w < y = (x, z)
| otherwise = piCalc' (w + 2) (stepReverseSign (4 / w) x) y (z + 1)