Haskell - How to modify existing function values - haskell

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

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 it return 5 instead of 3 in this code?

Hey guys I have a question regarding the following code: (I use python 3)
def foo (x):
def bar (z, x = 0):
return z + x
return bar(3, x)
foo(2)
Apparently the return value is 5. But no matter how I draw the frame, it comes out returning 3 on my paper. Could someone help me out here? Thanks :)
If I understand correctly your question, you're asking why the program is returning 5 ?
The bar definition in foo acts exactly as if it were defined outside foo function. x is shadowed but it acts like it was completely another variable.
So, when you call foo(2), it calls bar(3, 2) which returns 3+2 = 5.
Formatting the code helps understanding it.
bar(3,x) returns 3+x as x is provided (if x were not provided, it would have been 0 by default.
foo(2) returns bar(3,x) but as x is 2 then you receive 5 as the final response bar(3,2)

Global variable wrapped in a function

I'm learning Julia as part of my PhD in economics but I've come across an issue that doesn't make sense to me. I'm trying to write a function that performs some preliminary calculations then conducts a while loop and returns some value. I want to do this without using global variables. For some reason I can't get it to work. See the minimal working example below which returns a undefined variable error for z.
function test_me(n)
x = 2 + 1
y = x - 1
i = y
while i <= n
println(i)
i += 1
z = 3*i
end
return z
end
I can solve the problem easily by making z a global variable.
function test_me2(n)
x = 2 + 1
y = x - 1
i = y
while i <= n
println(i)
i += 1
global z = 3*i
end
return z
end
I'm confused as I was under the impression that by wrapping the while loop in a function implies that z is in the local scope and the global declaration is unnecessary. For example the code below works as expected.
function test_me3(n)
i = 1
while i <= n
println(i)
i += 1
z = 3*i
end
return z
end
I apologise if this issue is trivial. Any help is really appreciated. Thanks.
Just put a local z or alternatively a z = 0 before your while loop such that z is defined in the loop.
For more on this check out the scoping page of the Julia documentation and the local keyword docstring.
See also this question/answer: In Julia, is there a way to pass a variable from a local scope to the enclosing local scope?

Comprehension - Nested if-conditions in 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.

Haskell execution sequence

can anybody help me understand this code
solve s | s == 0 = Nothing
| s == 1 = Just 1
| otherwise =
check [solve (s-(x*2)) | x <- [1..9]]
check x = case x of
[] -> Nothing
(Nothing:xs) -> check xs
(x:xs) -> x
why this gives stack over flow when i tried to run it with even value, and is there any way in haskell where i can debug and see the actual value of the running program , like in eclipse we do ?
thanks
At least with GHCi, there's no way to "step" through code (Edit: no longer true, see comment below), but you can certainly add debug statements using Debug.Trace. In other words if you wanted to check all the recursive calls to solve you could say:
check [trace ("solving for " ++ show (s-(x*2)))) (solve (s-(x*2))) | x <- [1..9]]
There are cleaner ways to write that but that just illustrates the idea.
In this particular case, the reason it recurses infinitely is that the base cases of solve will never be reached. solve 2 for example, resolves to check [solve 0, solve -2, solve -4 ..., solve -16] and solve -2 resolves to check [solve -4, solve -6, ...] etc.
Stack overflow suggests an infinite recursion. Branching on the otherwise case of "solve"
is not guaranteed to terminate. I'm not sure what the code is supposed to be doing here, so I cannot suggest a fix. Hope that helps!
Adding to Dan's answer, you can simply push trace there in solve, and that'll show the problem.
solve s | s == 0 = Nothing
| s == 1 = Just 1
| otherwise =
trace (show s) $ check [solve (s-(x*2)) | x <- [1..9]]
You can rewrite that first parts using pattern matching instead, it's a lot nicer notation than guards (if-statements) ;)
solve 0 = Nothing
solve 1 = Just 1
solve s = check [solve (s - (x * 2)) | x <- [1..9]]
The list comprehension feed the range 1 through 9 to the solve method, which calls solve with
s - (x * 2) and honestly, I can't intuitively tell that that's gonna terminate... but let's consider some examples.
solve 2
Calling solve 2 will result in the following list, since Haskell is lazy that list won't have values until you (have side-effects) try and print these...
solve s - 1 * 2
solve s - 2 * 2
solve s - 3 * 2
solve s - 4 * 2
solve s - 5 * 2
solve s - 6 * 2
solve s - 7 * 2
solve s - 8 * 2
solve s - 9 * 2
A simple solve 2 will try solve -2 which will try and solve other things, and that' won't end.
solve s | s == 0 = Nothing
| s == 1 = Just 1
| otherwise =
check [solve (s-(x*2)) | x <- [1..9]]
In the case of solve 2:
(2 - (1 * 2)) = 0
(0 - (2 * 2)) = -2
et cetera.
I'm not sure about the debugging stuff, but that's why it's overflowing the stack. It's infinitely recursing.
check :: [Maybe a] -> Maybe a
check = Data.Maybe.listToMaybe . Data.Maybe.catMaybes
solve :: (Num a, Num b) => a -> Maybe b
solve 0 = Nothing
solve 1 = Just 1
solve s = solve (s-2)
here, it is pretty obvious that solve -1 and solve 5.3 will run infinite.
this version of solve will run just like a while loop.
the original version you posted will spam in every call unneeded stuff into your ram/stack.
you can rewrite this:
solve s = check [solve (s-x)|x<-[2,4..18]]
to this:
solve s = check [solve (s-2),solve (s-4),solve (s-6),solve (s-8),solve (s-10),solve (s-12),solve (s-14),solve (s-16),solve (s-18)]
but whenever solve (s-2) returns Nothing, then each solve (s-x) will return Nothing, because that value was already tested like this: solve ((((s-2)-2)-2)-2)
it is an exponential algorithm to test sth, which could be tested in linear time or calculated in constant time.
i suggest to read this book:
Haskell: The Craft of Functional Programming

Resources