In GHCI, I get these results:
div (-7) ( 2) = -4
div ( 7) (-2) = -4
div (-7) (-2) = 3
mod ( 7) ( 2) = 1
mod ( 7) (-2) = -1
mod (-7) ( 2) = 1
mod (-7) (-2) = -1
and div 4 (-3) is -2, and mod 4 (-3) is -2.
I can't understand how to get those results. Is there some laws or rules?
And what are right calculation steps ?
Usually it a good idea to first look at the documentation. For the mod function, we see:
mod :: a -> a -> a
integer modulus, satisfying
(x `div` y)*y + (x `mod` y) == x
So x `mod` y is calculated as:
mod x y = x - y * (div x y) -- logically equivalent definition
And:
div :: a -> a -> a
integer division truncated toward negative infinity.
So in case the division is -3.5, the div will return -4.
So:
mod 7 2 = 7 - 2*(div 7 2) = 7 - 2 * 3 = 7 - 6 = 1
mod 7 (-2) = 7 - (-2)*(div 7 (-2)) = 7 - (-2) * (-4) = 7 - 8 = -1
mod (-7) 2 = (-7) - 2 * (div (-7) 2) = (-7) - 2 * (-4) = (-7) + 8 = 1
mod (-7) (-2) = (-7) - (-2) * (div (-7) (-2)) = -7 - (-2) * 3 = -7 + 6 = -1
Related
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)))
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.
I found out this snippet of code which works, but I do not understand why it does. It converts an Int to its representation in binary.
repBinario::Int -> Int
repBinario 0 = 0
repBinario x = 10 * repBinario (x `div` 2) + x `mod` 2
I know what div and mod do. However, how does it place each number that comes from mod together?
In short, it multiplies the accumulated result by 10 on each iteration.
To get a clearer understanding of what's going on we can divide your function into two simpler ones. The first one will convert an integer into a list of binary digits. The other will then do exactly the thing that bothers you: concat a list of binary digits into an integer.
extractBinDigits :: Int -> [Int]
extractBinDigits =
unfoldr (\x -> if x == 0 then Nothing else Just (mod x 2, div x 2))
concatDigits :: [Int] -> Int
concatDigits =
foldr (\a b -> a + b * 10) 0
As you see we simply fold the list multiplying the accumulator by 10 on each step and adding each digit to it.
Then your original function becomes just this:
repBinario :: Int -> Int
repBinario =
concatDigits . extractBinDigits
Division now lets us inspect and reuse the finer pieces of our program providing us with greater flexibility. E.g., by adding another simple function you can now convert the integer into a string in one go:
showDigits :: [Int] -> String
showDigits =
reverse . map (chr . (+ 48))
repStringyBinario :: Int -> String
repStringyBinario =
showDigits . extractBinDigits
Let’s go through an example, then:
repBinario 5
Substitute definition of repBinario 5:
10 * repBinario (5 `div` 2) + 5 `mod` 2
Reduce div and mod:
10 * repBinario 2 + 1
^
Here we have produced our first digit, marked with ^.
Substitute definition of repBinario 2:
10 * (10 * repBinario (2 `div` 2) + 2 `mod` 2) + 1
^
Reduce div and mod:
10 * (10 * repBinario 1 + 0) + 1
^ ^
Substitute definition of repBinario 1:
10 * (10 * (10 * repBinario (1 `div` 2) + 1 `mod` 2) + 0) + 1
^ ^
Reduce div and mod:
10 * (10 * (10 * repBinario 0 + 1) + 0) + 1
^ ^ ^
Substitute definition of repBinario 0:
10 * (10 * (10 * 0 + 1) + 0) + 1
^ ^ ^
Reduce:
101
At each step, (`mod` 2) gets the least significant binary digit, and (`div` 2) shifts the number rightward, discarding the digit and passing the rest of the number recursively to divBinario. At the end, we do the opposite process: (+ d) adds the current digit to the result, and (* 10) shifts the number leftward so we can add more digits.
What you get is a decimal number that looks identical to the binary representation of the original input.
If you remove the multiplication by 10, you get popCount, a function that gives you the population count of a number—the number of 1 bits in its binary representation:
popCount 0 = 0
popCount x = popCount (x `div` 2) + x `mod` 2
popCount 5 == 2
I think it would be best to calculate this function for a small value by hand - this is possible since this is a pure function therefore you can replace left hand side with its definition (i.e. right hand side) - the fancy computer science word for this feature is "referential transparency".
repBinario 24 = 10 * repBinario (24 `div` 2) + 24 `mod` 2
= 10 * repBinario 12 + 0
= 10 * (10 * repBinario (12 `div` 2) + 12 `mod` 2)
= 100 * repBinario 6 + 0
= 100 * (10 * repBinario (6 `div` 2) + 6 `mod` 2)
= 1000 * repBinario 3 + 0
= 1000 * (10 * repBinario (3 `div` 2) + 3 `mod` 2)
= 10000 * repBinario 1 + 1000 * 1
= 10000 (10 * repBinario (1 `div` 2) + 1 `mod` 2) + 1000
= 10000 (10 * repBinario 0 + 1) + 1000
= 10000 (10 * 0 + 1) + 1000
= 10000 * 1 + 1000
= 11000
in those steps I just evaluated the function by its definition and used the fact that integer-addition/multiplication obey the law of distribution.
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]
I have some problems with the different types in Haskell, how can I solve this?
Couldn't match expected type Integer with actual type Int -> t0 -> t0
Thanks
isPrime :: Int -> Bool
isPrime number
| (number == 1) || (number == 2) = True
| even number = False
| otherwise = checkDiv number (fromInteger (`sqrt` number))
checkDiv :: Int -> Int -> Bool
checkDiv number divisor
| number == 2 = True
| (floor number `mod` divisor) == 0 = False
| otherwise = checkDiv number $ divisor - 1
I've figured out the modifications to get the code to compile, but it does not actually find primes. I had to change
fromInteger (`sqrt` number)
to
floor $ sqrt $ fromIntegral number
The backtick notation around a function name is to turn it in to an infix "operator" of sorts, so you could do
mod x y
or
x `mod` y
but not
`mod` x y
Next, you were using fromInteger instead of fromIntegral, which is the one that works on Ints (Int and Integer are different types). Finally, I removed the floor from number in the second guard of checkDiv, since number is already an Int.
isPrime :: Int -> Bool
isPrime number
| (number == 1) || (number == 2) = True
| even number = False
| otherwise = checkDiv number (floor $ sqrt $ fromIntegral number)
checkDiv :: Int -> Int -> Bool
checkDiv number divisor
| number == 2 = True
| (number `mod` divisor) == 0 = False
| otherwise = checkDiv number $ divisor - 1
So let's work through your code so that you can see what's going on. If I were to compute checkDiv 17 4 (4 is floor $ sqrt $ fromIntegral 17), it would perform
checkDiv 17 4
| 17 == 2 No
| 17 `mod` 4 == 0 No
| otherwise = checkDiv 17 (4 - 1) = checkDiv 17 3
checkDiv 17 3
| 17 == 2 No
| 17 `mod` 3 == 0 No
| otherwise = checkDiv 17 (3 - 1) = checkDiv 17 2
checkDiv 17 2
| 17 == 2 No
| 17 `mod` 2 == 0 No
| otherwise = checkDiv 17 (2 - 1) = checkDiv 17 1
checkDiv 17 1
| 17 == 2 No
| 17 `mod` 1 == 0 Yes = False
But 17 is prime! Do you see where your algorithm is doing something wrong?