Why does this create a StackOverflow Error? - haskell

I've started using Haskell lately, and defined this seemingly simple function:
f 0 = 1
f x = x * f x - 1
However, it results in this:
GHCi, version 8.2.1: http://www.haskell.org/ghc/ :? for help
Prelude> f 0 = 1
Prelude> f x = x * f x - 1
Prelude> f 10
*** Exception: stack overflow
Prelude>

Your factorial seems innocent, but it isn't. It's parsed like this:
f 0 = 1
f x = x * (f x) - 1
What happens if we use f 1?
f 1 = 1 * (f 1) - 1 = 1 * (1 * (f 1) - 1) - 1
= 1 * (1 * (1 * (f 1) - 1) - 1) - 1
= 1 * (1 * (1 * (1 * (f 1) - 1) - 1) - 1) - 1
= ...
I'm going to stop here. This will never end. It will build up a stack of parentheses, and at some the whole tower collapses and you end up with a stack overflow.
You have to use parentheses:
f 0 = 1
f x = x * f (x - 1)
Now we get the correct result:
f 1 = 1 * f (1 - 1) = 1 * f 0 = 1 * 1 = 1
Keep in mind that this works only in an implementation file. In GHCi you have to use multi-line mode or a semicolon:
ghci> f 0 = 1; f x = x * f (x - 1)
ghci> -- or
ghci> :{
ghci| f 0 = 0
ghci| f x = x * f (x - 1)
ghci| :}
Otherwise later definitions will shadow earlier ones. Note that your prompt might differ.

Related

Heron's method in haskell

I'm getting divide by zero exceptions in this code of heron's method, and I am kind of lost here.
epsilon:: Integral a => a
epsilon = 1
heron:: Integral a => a -> a
heron r = help 0
where
help x
| abs (heron' x - heron' (x + 1)) < epsilon = heron' (x + 1)
| otherwise = help (x + 1)
heron' 0 = 1
heron' x = (1 `div` 2) * (heron' (x-1) + (r `div` heron' (x-1)))
Any suggestions where in this code I have to look to solve this problem?
(1 `div` 2) is definitely a problem , but what do I need to write instead?
If you need division of this kind, you probably want to use (/) instead of div and Fractional instead of Integral. So:
epsilon:: Fractional a => a
epsilon = 1
heron:: (Fractional a, Ord a) => a -> a
heron r = help 0
where
help x
| abs (heron' x - heron' (x + 1)) < epsilon = heron' (x + 1)
| otherwise = help (x + 1)
heron' 0 = 1
heron' x = (1 / 2) * (heron' (x-1) + (r / heron' (x-1)))

Why does this recursive function for square-roots give the wrong result?

I made this tail-recursive function for computing square roots:
sqrt x n a = if n == 0 then a else sqrt x (n - 1) (a + x/a)/2
For some reason, it gives the wrong result when n is greater than 1, meaning when it's asked to improve the approximation, a, more than once. It returns a number that's closer and closer to 0 as n grows. I tried implementing the same recursive formula in different ways like this:
sqrt x n = if n == 0 then 1 else (a + x/a)/2 where a = sqrt x (n - 1)
sqrt x = 1:map (\a -> (a + x/a)/2) (sqrt x)
And that all works fine. It's only the first example that doesn't work and I can't figure out why, as much as I try.
The expression:
sqrt x n a = if n == 0 then a else sqrt x (n - 1) (a + x/a) / 2
is parsed as:
sqrt x n a = if n == 0 then a else (sqrt x (n - 1) (a + x/a)) / 2
So the sqrt x (n-1) (a+x/a) is seen as the numerator of a division by two. You should add brackets here:
sqrt x n a = if n == 0 then a else sqrt x (n - 1) ((a + x/a) / 2)
With the given, fix, we can for example calculate the square root of five as:
Prelude> sqrt 5 10 1
2.23606797749979
According to Wikipedia, it is:
2.23606797749978969640917366873127623544061835961152572427089…
so this is already quite close.

Haskell Says My Guard Has A Parse Error

So I've been playing with Haskell the past couple of days, and I decided I'd make a basic definition of the Fibonacci sequence. So I wrote this code:
main = do
fib :: (Integral a) => Int -> Int
fib x
| x == 0 = 0
| x == 1 = 1
| x >= 2 = fib (x - 2) + fib (x - 1)
do { print (fib 5) }
And I get an error message saying:
4:17: parse error on input `|'
I suspected tab errors, so I tried every whitespace fix I could find, but I just can't find what's wrong!
EDIT: So I did what people suggested, and I have this code now:
fib :: (Integral a) => Int -> Int
main = do
fib x
| x == 0 = 0
| x == 1 = 1
| x >= 2 = fib (x - 2) + fib (x - 1)
print (fib 5)
And I'm getting the same error.
You should define fib outside of main, not inside it. And then you should remove at least one of the dos from main.
The problem is that you are trying to define the function within do block without actually using any construct for defining things (like let).
Try defining the function outside the block:
fib :: (Integral a) => Int -> Int
fib x | x == 0 = 0
| x == 1 = 1
| x >= 2 = fib (x - 2) + fib (x - 1)
main = print (fib 5)
If you insist on defining the function locally (inside the expression that is formed by statements of the do block):
main = do
let
fib :: (Integral a) => Int -> Int
fib x | x == 0 = 0
| x == 1 = 1
| x >= 2 = fib (x - 2) + fib (x - 1)
print (fib 5)
Notice how let is used to bind a new variable fib to the function you want.
You can also define fib locally to main outside of the do block. Do bear in mind that do is syntactic sugar for the use of various monadic binding functions, and so the syntax accepted within it is not quite the same as that accepted outside it. And, in fact, your main doesn't even require the do block because you just call print rather than chaining any IO actions together.
main = let
fib x | x == 0 = 0
| x == 1 = 1
| x >= 2 = fib (x - 2) + fib (x + 1)
in
print (fib 5)
Or you could use where:
main = print (fib 5)
where
fib x | x == 0 = 0
| x == 1 = 1
| x >= 2 = fib (x - 2) + fib (x + 1)
They're the same, the question is just where the local binding actually goes. let..in gives you a new block where the new bindings are in scope, while where makes its bindings available in the scope of the function it's attached to.
If, as seems eventually likely, you do want a do block as well so you can do multiple IO actions, you can just put that in place of the call to print, like so:
main = let
fib x | x == 0 = 0
| x == 1 = 1
| x >= 2 = fib (x - 2) + fib (x + 1)
in
do print (fib 5)
print (fib 6)

why do I get a type error here?

I'm sitting on this for over 4 hours and can't wrap my head aroud it.
I try to run the following code:
top = 100 :: Int
couplesToOne num
|num<0 = error "num<0"
|num==0 = 0
|num `mod` 2 == 0 = num `div` 2
|num `mod` 2 == 1 = (num+1) `div` 2
|otherwise = error "otherwise"
numInBig n bigSide
|(bigSide^2 <= n) = couplesToOne (n-1)
|(bigSide^2 > n) = couplesToOne (n-1) - (couplesToOne (floor(sqrt(bigSide^2 - n))))
|otherwise = error "otherwise"
ans = map (numInBig top) [3..((div top 4) + 1)]
and I get the following error message:
No instance for (RealFrac Int) arising from a use of `numInBig'
In the first argument of `map', namely `(numInBig top)'
In the expression: map (numInBig top) [3 .. ((div top 4) + 1)]
In an equation for `ans':
ans = map (numInBig top) [3 .. ((div top 4) + 1)]
enter code here
I figured out (probably?) that this is because of the "sqrt" that returns a float but that's why I added the floor that's supposed to return an Integral.
can you please help me?
This works:
top = 100 :: Int
couplesToOne num
|num<0 = error "num<0"
|num==0 = 0
|num `mod` 2 == 0 = num `div` 2
|num `mod` 2 == 1 = (num+1) `div` 2
|otherwise = error "otherwise"
numInBig n bigSide
|(bigSide^2 <= n) = couplesToOne (n-1)
|(bigSide^2 > n) = couplesToOne (n-1) - couplesToOne (floor(sqrt(fromIntegral(bigSide^2 - n))))
|otherwise = error "otherwise"
ans = map (numInBig top) [3..((div top 4) + 1)]
You need an extra fromIntegral because sqrt::Floating a => a -> a is not defined on Int.
> ans
[50,50,50,50,50,50,50,50,48,47,46,45,44,44,43,43,42,41,41]

Print Diamond Pattern using Haskell

I need to write a Haskell program that will generate a diamond output recursively.
Here is some sample output for given input
input : 1
output :
*
* *
*
input : 2
output :
*
* *
*
* *
* * * *
* *
*
* *
*
input : 3
output :
*
* *
*
* *
* * * *
* *
*
* *
*
* *
* * * *
* *
* * * *
* * * * * * * *
* * * *
* *
* * * *
* *
*
* *
*
* *
* * * *
* *
*
* *
*
I wrote following functions:
next 0 = [1,0,1]
next n = map (+3^n) (next (n-1)) ++ next (n-1) ++ map (+3^n) (next (n-1))
lpad n = map (++"*") (zipWith ($) (map (take)(next (n-1))) ((repeat(repeat ' '))))
pretty n = putStrLn $ intercalate "\n" $ lpad n
which gives following outputs:
pretty 1
*
*
*
pretty 2
*
*
*
*
*
*
*
*
*
Can anyone help me with the remaining halves? Thanks in advance.
For n==0, next n describes the whole picture up to mirroring. This is not the case anymore for greater n. So, in a first step, we change the next function to output a symmetric picture:
mmap = map . map
next :: Int -> [[Int]]
next 0 = [[1],[0,2],[1]]
next n = sn ++ map (\a -> a ++ map (+2*3^n) a) nn ++ sn
where
nn = next (n - 1)
sn = mmap (+3^n) nn
Now, next n describes the positions of all stars. To print them, we first compute the relative distances.
diffs :: [Int] -> [Int]
diffs (x:xs) = x: diffs' x (xs)
where
diffs' x (y:ys) = y - x - 1 : diffs' y ys
diffs' _ [] = []
diffs [] = []
lpad :: Int -> [[Char]]
lpad = map (concatMap $ \n -> replicate n ' ' ++ "*") . map diffs . next'
Applied to one line, diffs returns the list of the number of spaces we need to put before each star and lpad generates the picture from that. Print it as before:
pretty :: Int -> IO ()
pretty n = putStrLn $ unlines $ lpad n
I liked the task, so I wrote an alternative solution.
We could build it up, a bit like you would with a pretty printer. Look into the pretty package to take these ideas and use them properly, but let's stick to plain old [String] for this.
First let's make a blank grid
blank :: Int -> [String]
blank n = replicate (3^n) $ replicate (3^n) ' '
Then let's define a diamond.
diamond :: Int -> [String]
diamond 0 = ["*"]
diamond n = let
o = diamond (n-1)
x = blank (n-1) in
joinMatrix [[x,o,x]
,[o,x,o]
,[x,o,x]]
But how can we join this matrix of [String] together?
First get all the Strings that should be concatenated together next to each other instead of under each other using transpose, then concat them all:
joinLine :: [[String]] -> [String]
joinLine = map concat.transpose
To do that to a whole matrix we need to join the lines on each row, then concat all the lines together into one list of lines:
joinMatrix :: [[[String]]] -> [String]
joinMatrix = concat.map joinLine
helper functions for printing:
put = mapM_ putStrLn
d n = put $ diamond n
You could argue that the numerical solution is more efficient, and it is, but d 4 is the largest that fits on my screen and isn't slow. You could also argue that this solution is clearer.
*Main> d 0
*
*Main> d 1
*
* *
*
*Main> d 2
*
* *
*
* *
* * * *
* *
*
* *
*
(It works for higher n too, but they would make this post unnecessarily long on the page.)
This is derived from AndrewC's solution. The space blocks are recursively generated and I prefer to use operators to make the code clearer:
diamond
= putStr
. unlines
. fst
. (iterate f (["*"], [" "]) !!)
where
f (d, e)
= ( e + d + e
++ d + e + d
++ e + d + e
, e + e + e
++ e + e + e
++ e + e + e
)
(+) = zipWith (++)
A generalization.
If we would like to have this:
+
- -
+
- -
+ + + +
- -
+
- -
+
- -
+ + + +
- -
+ + + +
- - - - - - - -
+ + + +
- -
+ + + +
- -
+
- -
+
- -
+ + + +
- -
+
- -
+
then the solution is star 3 where
star
= putStr
. unlines
. (\(d, p, e) -> d)
. (iterate f (["-"], ["+"], [" "]) !!)
where
f (d, p, e)
= ( e + p + e
++ d + e + d
++ e + p + e
, e + d + e
++ p + e + p
++ e + d + e
, e + e + e
++ e + e + e
++ e + e + e
)
(+) = zipWith (++)

Resources