Comprehension - Nested if-conditions in Haskell - haskell

i try to become familiar with the if-condition statements in haskell
assume that i´ve an argument x and i try the following in haskell
functionname x = if x > 0 then x-5
if x-5 == 0 then 1
else if x-5 /= 0 then functionname x-5
else if x-5 < then 0
so, the idea was to subtract 5 from x, check if the result is 0, if yes, then give a 1.
If not then invoke the function again with the expression x-5.
If the result of x-5 is negative then give a 0.
so, my questions: Would that be correct? Because when i try that, i´ve got a message like parse error on input 'functionname'.
how can i fix that problem? Are the if-else conditions wrong ?
programm :: Int -> Bool
programm x | x > 0 =
if z == 0 then True
else if z < 0 then False
else programm z
where
z = z-2
programm x | x < 0 =
if z == 0 then True
else if z > 0 then False
else programm z
where
z = z+2
so, i wanted to have the possibility to decide of a given number is even. So, i modify your solution a little bit. its the same but, at the beginning of the two declarations i said : x > 0 = .... and x < 0 =...
Because i want to say that for example -4 is also even. for that reason: the first declarations should handle the positive even numbers and the second declarations handles the negative even numbers.
when i give that to the compiler, then the message : Exception appears. Where i ve made the mistake?

Use guards to make things clear:
functionname x
| x > 0 = x - 5
| x - 5 == 0 = 1
| x - 5 /= 0 = functionname (x - 5)
| x - 5 < 0 = 0

Every if needs to have an else clause associated with it.
The very first one doesn't and the very last one doesn't either.
This works just fine:
functionname x = if x > 0 then x-5
else if x-5 == 0 then 1
else if x-5 /= 0 then functionname x-5
else if x-5 < 0 then 0 else 1

so, the idea was to subtract 5 from x, check if the result is 0, if
yes, then give a 1. If not then invoke the function again with the
expression x-5. If the result of x-5 is negative then give a 0.
That might be written like this:
functionname x =
if x' == 0 then 1
else if x' < 0 then 0
else functionname x'
where
x' = x - 5
Here, I use a where clause to locally define x' as x - 5 and then use it for the tests and the recursive call. Your first branch, if x > 0 then x-5, does not appear in your description of what function should do (it gives x - 5 results as result whenever x is larger than zero, which is probably not what you want). Also, note that every if needs an else as well as a then.
so, i wanted to have the possibility to decide of a given number is
even. So, i modify your solution a little bit. its the same but, at
the beginning of the two declarations i said : x > 0 = .... and x < 0
=... Because i want to say that for example -4 is also even. for that reason: the first declarations should handle the positive even numbers
and the second declarations handles the negative even numbers.
First of all, in the second version of your function the definition in the where clause should be z = x + 2, as z = z + 2 will not terminate. This being an evenness test, you also want to perform the tests on x rather than z. With that fixed, your solution with nested conditionals should work fine (note, however, that you are not treating the x == 0 case; the first guard should be x >= 0). There is a more elegant way of writing the function, though:
myEven :: Int -> Bool
myEven x = myEven' (abs x)
where
myEven' x
| x == 0 = True
| x < 0 = False
| otherwise = myEven' (x - 2)
abs is the familiar absolute value function, while myEven' amounts to the x > 0 branch of your original definition. Taking the absolute value of x is the easiest way to avoid writing two nearly equal branches to handle the negative and non-negative cases.
N.B.: While this is probably just a learning exercise, if you ever need to find whether a number is even there is an even function available from the Prelude. There is also mod if you need to test divisibility for other numbers.

Related

Why piece-wise definition of a function in Haskell depends on the order they specified?

Being a beginner, I am working on an example of the function with piece-wise definition.
pts 1 = 10
pts 2 = 6
pts x = x
The code above works as I expected. However, when I tried to change the order to
pts x = x
pts 1 = 10
pts 2 = 6
I got a warning
warning: [-Woverlapping-patterns] Pattern match is redundant
and the last two statements look to be ignored by the compiler.
I did not manage to Google an answer, I would be grateful for a link to the explanation.
In Haskell, patterns in function definitions like this are checked from top to bottom. So you first example is the same as:
pts x =
if x == 1 then 10
else if x == 2 then 6
else x
And your second definition is similar to:
pts x =
if True then x
else if x == 1 then 10
else if x == 2 then 6
else undefined
Clearly, in this second example the first branch is always taken, the rest are redundant.
Haskell goes through the patterns top-to-bottom and picks the first one that matches the input. In this case, x matches any input, because it's just a plain variable, so if this is on top it is always chosen immediately and the other patterns not even considered. It's this decision:
pts x = if True then x
else if ... -- irrelevant
If it comes at the bottom, it is only considered after the other patterns have failed, and because these match specifically only a single number, that will happen more often than not.

Why does using modulus and floor division in Python return a reversed binary number?

I'm new to programming, and I don't understand why this code returns the binary number of the input.
x = int(input())
while x > 0:
print(x % 2, end='')
x = x // 2
For example, when I enter 6, I expect it to return 0 (6 % 2 = 0, 0 // 2 = 0), but it returns 011.
I stated contemplating this because, in an assignment, we're supposed to use this coding to help us reverse the output (while using a string) but I don't know how to reverse it when I don't know why it works.
The answer of 011 is correct for your code, just trace it thru. You start with 6%2 so you get a 0. Then 6 floor 2 is 3, which is then the x for the next iteration so it becomes 3%2 which is 1 and the final iteration creates the last 1. Remember that you're not changing the value of x in the print statement, it only changes in the last line.

Haskell - How to modify existing function values

i have a basic question regarding Haskell that boggles my mind since i am new to functional programming.
i've got simple functions for example
foo 1 1 = 0
foo 1 2 = 1
foo 2 1 = 1
foo 2 2 = 0
and i want to change the function values depending on a condition via another function (for example from 1 to 0, if the value is 1). How can i do that? I'm comming from python and am somehow stuck in the way of thought that i can simply assign the new value in the function body.
im trying something along this lines:
changeValue x y
|(foo x y == 1) = foo x y = 0
A little hint would be appreciated, since it feels like a simple question that i just can't find a solution for. Thanks!
Maybe having a look at http://learnyouahaskell.com/syntax-in-functions helps? Think of haskell functions as mathematical functions, there's no assignment there either.
Anyway, you can ask an other function for a value to compare to, and e.g. in that case return 1:
foo 0 1 = 1
foo x y
| otherfunction x y == 7 = 1
| otherwise = 0

and operator with random

i dont understand why the code bellow doesnt work properly. If both variables a and b < 0 it should print that both numbers are negative,else the last message. But it just dont work so, what am i doing wrong? please help!
import random
while True:
input()
a=random.randint(-9,9)
b=random.randint(-9,9)
print(a,b)
if a and b < 0:
print("2 negative numbers:",a,b)
else:
print("one or both of the numbers are positive!")
I'm running this on python 3.4.
I think you're a little confused about how operators distribute.
When you have
if a and b < 0
it doesn't mean
if (both a and b) < 0
but instead
if (a) and (b < 0)
which is equivalent to
if (a != 0) and (b < 0)
since "numeric zero of all types ... evaluates to false" (see the reference on booleans on docs.python.org)
Instead, you want
if a < 0 and b < 0
which will tell you if both a and b are less than zero.
Evaluating Both Operands will resolve the issue. Here both Operands are expressions which results in true or false, so if both result in true; you will get your required result.
if ((a < 0) and (b < 0)):
You are evaluating just a, not it's relation to 0:
if a < 0 and b < 0:
This:
a and b < 0:
Is equivalent to this:
(a) and (b < 0):
(a) is False when a equals 0 and True otherwise. Therefore, due to short-circuiting b < 0 isn't even evaluated.
As a fix you may use all method:
all(i < 0 for i in (a, b))

list comprehension and exclusion in one value

I'm having an issue in python3. I want to exclude 0 as one of the values, however I can't seem to make that happen. I attempted adding another "and if" parameter but the result still included 0.
I want the values that are multiples of 6 between 1 and 100. 0 is clearly not one of them.
x for x in range(100) if x % 6 == 0
The most direct answer is just
range(6, 101, 6)
But your original approach should work if you do something like:
[x for x in range(101) if x % 6 == 0 and x != 0]
(no and if needed, it's just a single if clause with a compound test).
Try:
x for x in range(100) if x%6 == 0 and x != 0
or simply:
x for x in range(1,100) if x%6 == 0
If you want to exclude 0, don't include it in the first place :
range(1, 100)

Resources