i wrote a pow function in ocaml and by mistake a wrote this
let rec pow x y acc = if y = 1 then acc else pow x (y-1) x*x;;
this function can be called with any value of acc and output the correct answer, but this must output x^2 .
this is the correct functon :
let rec pow x y acc = if y = 0 then acc else pow x (y-1) x*acc;;
and call this function with the value of acc of 1.
my question is why first function give the correct output ?
The key is that function application has higher precedence than binary operators. In the case at hand, the else term is equivalent to (pow x (y-1) x) * x, not pow x (y-1) (x*x).
Related
I am new to haskell code. I tried to compute the sum of squares of negative integer in a list using foldr high order.
sumsq :: Int -> Int
sumsq n = foldr op 0 [1..n]
where op x y = x*x + y
Please help to explain each line of code and give any solution if error in this code
When using "where", important to follow the indentation rule.
Here lambda will be appropriate
sumsq n = foldr (\x y -> x*x + y) 0 [1..n]
I tried the no tail recursion version of Russian Peasant exponentiation and it returned like this:
let rec fast_expNTR (base, power) =
match power with
|0->1
|n-> if n mod 2=0 then fast_expNTR (square base, power/2)
else base * fast_expNTR(square base , power/2)
But in else base*fast_expNTR(square base , power/2), it says expression is expected of type float but was given a type int. I don't understand the error.
Also, here is my attempt on tail-recursive fast exponentiation:
let fast_exp (base , power)=
let rec helper (acc ,acc2,p)=
if p=0 then acc * acc2
else if p mod 2 =0 then helper(int_of_float (square (float_of_int acc)),acc2, p/2)
else helper(int_of_float(square (float_of_int acc)),acc * acc2, p/2)
in helper(base,1,power)
But it didn't compute the correct result. Please help
Hint: Your function square has type float -> float and * is the integer multiplication.
I need to write a code that composes a function, f (x), with itself N times using recursive function.
What I wrote is:
let f x = x + 1 (*it can be any function*)
let rec compose n f x = if n = 0 then
"Can't compose anymore"
else compose (n-1) f (f x);;
which is obviously not right. I know the code is not finished, but I do not know how to continue. Am I on the right path or not? Can you tell me how to solve the problem?
You are on the right path. Based on the requirements, I would try to start from those equations:
compunere 1 f x == f x
The above says that applying f once to x is exactly the same as doing (f x).
compunere 2 f x == f (f x)
Likewise, applying f twice should compute f (f x). If you replace (f x) by a call to compunere, you have:
compunere 2 f x == f (f x) = f (compunere 1 f x)
The general pattern of recursion seems to be:
compunere n f x == f (compunere (n - 1) f x)
Note that the most general type of f is a -> b, but when f is called again with a value of type b, that means that a and b should be the same type, and so f really is an endomorphism, a function of type a -> a. That is the case for N >= 1, but in degenerate case of N=0, you could have a different behaviour.
Applying f zero time to x could mean "return x", which means that compunere could theoretically return a value of type a for zero, for any f being a a -> b function, a and b possibly distinct; you could distinguish both cases with more code, but here we can simply let the typechecker enforce the constraint that a = b in all cases and have an uniform behaviour. You can also make 0 invalid (like negative numbers) by throwing an exception (negative applications could theoretically be postitive applications of the inverse function, but you cannot compute that when knowing nothing about f; f could be non-invertible).
Your code is a little bit different:
compunere 3 f x == (compunere 2 f (f x))
== (compunere 1 f (f (f x)))
== (compunere 0 f (f (f (f x))))
...
The advantage of your approach is that the recursive call to compunere is directly giving the result for the current computation: it is in tail position which allows the compiler to perform tail-call elimination.
When you reach N=0, the value locally bound x gives the result you want. Here, for N=0 as an input, the only natural interpretation is also to return x.
I want to make a recursive function that sums the integers between two values. I'm doing:
let rec sum_between x y =
if x>y then sum_between y x else
if x=y then x else x + sum_between x+1 y ;;
But I get the error: This expression has type int -> int
but an expression was expected of type int
What am I doing wrong?
Function application has high precedence in OCaml. You need to parenthesize an expression when it's an argument to a function.
Your code
sum_between x+1 y
is parsed like this:
(sum_between x) + (1 y)
You need parentheses:
sum_between (x + 1) y
(Same answer as Edgar Aroutiounian but more helpful detail I hope.)
I am trying to calculate the square root of a number by Ocaml, this is my code :
let isclose x y = abs_float(x -. y)<0.001;;
let average x y = (0.5*.x)+.(0.5*.y);;
let rec guess x y = if isclose y (x /. y) then y else guess x (average y x/.y);;
let sqr x = guess x 1.;;
then, typing
sqr 1.;;
gives 1 as expected, but typing
sqr 2.;;
lasts undefinitely.
Can one help with my error (I tested the algo in Python and it works as expected).
Thanks for help
You want this:
let rec guess x y =
if isclose y (x /. y) then y else guess x (average y (x/.y))
Note the extra parentheses.
The meaning of
average y x /. y
is
(average y x) /. y
Whereas you want:
average y (x /. y)