Recursive addition in Haskell - haskell

The problem:
You are given a function plusOne x = x + 1. Without using any other (+)s, define a recursive function addition such that addition x y adds x and y together.
(from wikibooks.org)
My code (it does not work -- endless loop):
plusOne x = x + 1
addition x y
| x > 0 = addition (plusOne y) (x-1)
| otherwise = y
Questions:
How to connect the plusOne function to the addition recursive function?
How should it be written?

You are mixing up x and y in your recursive case
addition x y | y > 0 = addition (plusOne x) (y - 1) -- x + y == (x + 1) + (y - 1)
| otherwise = x -- x + 0 = x

using == and 0
addition = add 0 where
add a y x | a == y = x
| otherwise = add (plusOne a) y (plusOne x)

Related

Weird behavior of (^) in Haskell

Why does GHCi give incorrect answer below?
GHCi
λ> ((-20.24373193905347)^12)^2 - ((-20.24373193905347)^24)
4.503599627370496e15
Python3
>>> ((-20.24373193905347)**12)**2 - ((-20.24373193905347)**24)
0.0
UPDATE
I would implement Haskell's (^) function as follows.
powerXY :: Double -> Int -> Double
powerXY x 0 = 1
powerXY x y
| y < 0 = powerXY (1/x) (-y)
| otherwise =
let z = powerXY x (y `div` 2)
in if odd y then z*z*x else z*z
main = do
let x = -20.24373193905347
print $ powerXY (powerXY x 12) 2 - powerXY x 24 -- 0
print $ ((x^12)^2) - (x ^ 24) -- 4.503599627370496e15
Although my version doesn't appear any more correct than the one provided below by #WillemVanOnsem, it strangely gives the correct answer for this particular case at least.
Python is similar.
def pw(x, y):
if y < 0:
return pw(1/x, -y)
if y == 0:
return 1
z = pw(x, y//2)
if y % 2 == 1:
return z*z*x
else:
return z*z
# prints 0.0
print(pw(pw(-20.24373193905347, 12), 2) - pw(-20.24373193905347, 24))
Short answer: there is a difference between (^) :: (Num a, Integral b) => a -> b -> a and (**) :: Floating a => a -> a -> a.
The (^) function works only on integral exponents. It will normally make use of an iterative algorithm that will each time check if the power is divisible by two, and divide the power by two (and if non-divisible multiply the result with x). This thus means that for 12, it will perform a total of six multiplications. If a multiplication has a certain rounding-off error, that error can "explode". As we can see in the source code, the (^) function is implemented as:
(^) :: (Num a, Integral b) => a -> b -> a
x0 ^ y0 | y0 < 0 = errorWithoutStackTrace "Negative exponent"
| y0 == 0 = 1
| otherwise = f x0 y0
where -- f : x0 ^ y0 = x ^ y
f x y | even y = f (x * x) (y `quot` 2)
| y == 1 = x
| otherwise = g (x * x) (y `quot` 2) x -- See Note [Half of y - 1]
-- g : x0 ^ y0 = (x ^ y) * z
g x y z | even y = g (x * x) (y `quot` 2) z
| y == 1 = x * z
| otherwise = g (x * x) (y `quot` 2) (x * z) -- See Note [Half of y - 1]
The (**) function is, at least for Floats and Doubles implemented to work on the floating point unit. Indeed, if we take a look at the implementation of (**), we see:
instance Floating Float where
-- …
(**) x y = powerFloat x y
-- …
This thus redirect to the powerFloat# :: Float# -> Float# -> Float# function, which will, normally be linked to the corresponding FPU operation(s) by the compiler.
If we use (**) instead, we obtain zero as well for a 64-bit floating point unit:
Prelude> (a**12)**2 - a**24
0.0
We can for example implement the iterative algorithm in Python:
def pw(x0, y0):
if y0 < 0:
raise Error()
if y0 == 0:
return 1
return f(x0, y0)
def f(x, y):
if (y % 2 == 0):
return f(x*x, y//2)
if y == 1:
return x
return g(x*x, y // 2, x)
def g(x, y, z):
if (y % 2 == 0):
return g(x*x, y//2, z)
if y == 1:
return x*z
return g(x*x, y//2, x*z)
If we then perform the same operation, I get locally:
>>> pw(pw(-20.24373193905347, 12), 2) - pw(-20.24373193905347, 24)
4503599627370496.0
Which is the same value as what we get for (^) in GHCi.

Possibility of having parameterized definitions in haskell?

Is there a way to compactly write multiple definitions in haskell via case, without having to repeat, other than the input parameters, the exact same syntax? The only possible solution I can imagine so far is a macro.
Below is an example of defining binary max and min functions. Can we compress
max' x y
| x > y = x
| otherwise = y
min' x y
| x < y = x
| otherwise = y
into something like
(max',min') x y
| x (>,<) y = x
| otherwise = y
?
Edit:
I know this allows us to parametrize over the "grumpy face", but it seems like there still could be a more succinct form.
maxmin x y f
| f x y = x
| otherwise = y
max' x y = maxmin x y (>)
min' x y = maxmin x y (<)
Well, you can always do this:
select op x y
| x `op` y = x
| otherwise = y
max' = select (>)
min' = select (<)
I.e. extract the common parts into a function and turn the differences into parameters.

Infinite loop in recursive Haskell function

Hmm... why does this function ends in an infinite loop when evaluating for any integer > 3?
smallestMultiple n = factors [2..n] where
factors [] = []
factors (h:xs) = h:(factors $ filter ((<)1) [div x h|x<-xs])
where
div x y
|x `mod` y ==0 = x `div` y
|otherwise = x
It appears that the main problem is that you define a local version of div:
div x y
| x `mod` y == 0 = x `div` y
| otherwise = x
Since bindings in where clauses (as well as in let) are recursive, the div on the right hand side of the first case refers to the same div you're defining! You can fix this by using a different name, like div':
div' x y
| x `mod` y == 0 = x `div` y
| otherwise = x

Haskell - too few arguments

I want to write a Haskell program that calculates the sum of numbers between 2 given numbers.
I have the following code:
sumInt :: Int -> Int -> Int
sumInt x y
| x > y = 0
| otherwise = x + sumInt x+1 y
But when I compile it I get the following error:
SumInt is applied to too few arguments.
I don't understand what I'm doing wrong. Any ideas?
You need parentheses around x+1:
| otherwise = x + sumInt (x + 1) y
The reason is that function application binds more tightly than operators, so whenever you see
f x <> y
This is always parsed as
(f x) <> y
and never as
f (x <> y)

Haskell - Parameter count that fit criteria?

Let's say I have a function:
isOne :: Int -> Int -> Int
isOne x y =
Then if x == 1 and y != 1 then it returns 1 (one of the parameters equals 1), if x == 1 and y == 1 it returns 2 (because both are 1), if x != 1 and y != 1 it returns 0 etc.
I can't figure out how to do more than a single check with an if statement (or using cases).
Why, you just need to translate your english to Haskell:
if (x==1) && (y /= 1) then 1
else if (x/=1) && (y==1) then 1
...
But you really want:
isOne 1 1 = 2
isOne 1 _ = 1
isOne _ 1 = 1
isOne _ _ = 0
or, even shorter:
isOne x y = fromEnum (x==1) + fromEnum (y==1)
The easiest way to this is with pattern matches. You can define a function by cases, which are interpreted in the order at which they occur
isOne 1 1 = 2
isOne 1 _ = 1
isOne _ 1 = 1
isOne _ _ = 0
alternatively, you can use guards
isOne x y | (x == 1) && (y == 1) = 2
| (x == 1) && (y != 1) = 1
| (x != 1) && (y == 1) = 1
| otherwise = 0
again, these are checked from top to bottom. That is, if the first guard matches then it goes with the first equation, otherwise it tries the second, and so on. This can also be written
isOne x y | (x == 1) && (y == 1) = 2
isOne x y | (x == 1) && (y != 1) = 1
isOne x y | (x != 1) && (y == 1) = 1
isOne x y | otherwise = 0
or
isOne x y | (x == 1) && (y == 1) = 2
isOne x y | (x == 1) || (y == 1) = 1
isOne x y | otherwise = 0
another way of doing it would be to use an if then else expression.
isOne x y = if (x == 1) && (y == 1)
then 2
else if (x == 1) || (y == 1) then 1 else 0
or perhaps you could try doing
isOne x y = (go x) + (go y) where
go 1 = 1
go _ = 0
or any of dozens of other ways...
Method 1
Use paired case statements
isOne x y = case (x, y) of
(1, 1) -> 2
(1, _) -> 1
(0, 0) -> 0
...
Method 2
Use nested if statements
isOne x y = if x == 1 then (if y == 1 then 2 else 1) else 0
I'd second using either direct pattern matching in the function definition, or case on tuples.
But the most readable alternative would IMO be length [ q | q<-[x,y], q==1 ].

Resources