In OCaml, the [#tailcall] annotation lets you assert that a particular function-call is a tail call (and so hopefully your whole function is tail recursive). The question is: Where do I place the annotation exactly?
Obvious, easy example:
let rec f = function
| 0 -> 0
| x -> (f [#tailcall]) (x - 1) (* works like a charm *)
But I don't see how I can do it in "less obvious" places:
let rec f = function
| 0 -> 0
| x -> (|>) (x - 1) f (* uh? *)
I can see from the assembly code that the latter example is recognized as tail recursive by the compiler. So until someone implements [#tailrec]: Where exactly do I place my [#tailcall] annotations? (if it's possible at all in the 2nd example)
The docs say in subsection 18.1 that
“ocaml.tailcall” or “tailcall” can be applied to function application in order to check that the call is tailcall optimized. If it it not the case, a warning (51) is emitted.
Since your second example does not apply f, the attribute is not applicable in this context.
did you try :
let rec f = function
| 0 -> 0
| x -> (|>) (x - 1) (f[#tailcall])
Related
Where is the difference, I do not understand the purpose of the in keyword
let pow x =x*x;;
let y = 3;;
pow 3 + y;;
let pow x =x*x in
let b = 3 in
pow 3 + b;;
The declaration let <var> = <expr> can appear only at the top level of a module. It's used to define a global name of the module. If you imagine your two examples as independent modules, the first one declares two global names, pow and y.
The expression let <var> = <expr1> in <expr2> is just an expression in which var is a local variable. In your second example you are declaring no global names.
When typing into the toplevel, you are defining a module. But the module tends to fly by while you're thinking of other things. So you might not notice the difference. If you put your two examples into separate files named a.ml and b.ml, there would be easily observable differences. Namely, the names A.pow and A.y would be defined, but there would be no global names defined in module B.
To augment #JeffreyScofield's answer, let ... in ... provides an excellent tool to organize your code and keep it tidy.
Consider making a trivial recursive function to sum a list of integers.
let rec sum lst =
match lst with
| [] -> 0
| x::xs -> x + sum xs
But then you get a little further into your studies of functional programming and decide it would be best if sum were tail-recursive, so you need a helper function that takes an accumulator, and then sum simply needs to call that function.
let rec sum_helper lst acc =
match lst with
| [] -> acc
| x::xs -> sum_helper xs (x + acc)
let sum lst = sum_helper lst 0
But you don't really need sum_helper except in the context of sum, and having it hang out accessible at the toplevel clutters your namespace, so you can use let ... in ... to solve this.
let sum lst =
let rec sum_helper lst acc =
match lst with
| [] -> acc
| x::xs -> sum_helper xs (x + acc)
in
sum_helper lst 0
Thanks for your answers, these helped me to come to following short answer (as Nalin Ranjan mentioned in the comment above:
it is the ocamls way of scoping
let pow x =x*x;; (* global scope *)
pow 3;;
let pow2 x =x*x in (* local sope *)
pow2 3 + pow 4;; (* pow2 is only available here*)
pow 2;;
pow2 2;; (* not available here *)
Please correct me if I'm wrong.
Hello guys I am trying to make a simple recursive method that simply takes in an accumulator and a target value. Then add one to the accumulator until it reaches the target value. I am very new to Ocaml but have a decent background in java.
I wrote up a quick snippet of code that shows what I want to do in java:
public static int rec(int acc,int target) {
if (acc == target) {
return 0;
} else {
return rec(acc+1, target);
}
}
here is my attempt to mimic this code in Ocaml:
let h_sequence x =
let rec helper acc x = function
| acc -> x
| _ -> helper acc+1 x
in
helper 0 x;;
however I get the following error:
Error: This expression has type 'a -> 'b -> 'a
but an expression was expected of type int
Here is how I am trying to understand the Ocaml code. So we have a function h_sequence that has a paramater x. Inside of the function h_sequence we have a recursive function named helper which has two paramaters acc and x. If acc = x then return x. Else start the recursion by passing in helper, add one to the acc and then return x. And after the in it is passing the helper function, setting 0 for the acc and setting x as x. Please let me know if my logic is off. Any help will be much appreciated!
edit new code:
let h_sequence x =
let rec helper acc x =
if acc = x then
acc
else
helper (acc+1) x
in
helper 0 x;;
As #Flux says, your helper function has 3 parameters. You should also be aware that the pattern acc will match all values. Patterns consist essentially of constants, and any names appearing in a pattern will match (and be bound to) any corresponding value.
To compare x against acc you should just use an if statement.
Since you don't really want to use pattern matching, you can simplify things by removing function. You'll end up with something like this for the helper function:
let rec helper acc x =
if x = acc then (* One of the cases *)
else (* The other case *)
... we have a recursive function named helper which has two parameters acc and x.
You are getting the error because the recursive function helper actually has three "parameters": acc, x, and another "parameter" that that is matched using function. The error message has given you this clue ('a -> 'b -> 'a).
Let's now look at the helper function:
let rec helper acc x = function
| zzz -> x (* Equivalent to `| _ -> x` *)
| _ -> helper acc+1 x
Mistakes:
function does pattern matching. Everything will match the pattern zzz, which means that the next pattern (| _ -> helper acc+1 x) is useless because it will never be matched. Note that I've changed the pattern's name from your acc to zzz in order to emphasize that function actually matching patterns.
helper acc+1 x is equivalent to (helper acc) + 1 x, which is not what you want. It should be helper (acc+1) x instead.
Solution
let rec helper acc x =
if acc >= x then 0
else helper (acc+1) x
You should use >= instead of = to handle the case where x is negative.
I have a list composed by several couples of numbers:
[(1,2);(3,4);(5,6);(7,8)]
I want to remove the the first element (the head) from the list, so the output should be:
[(3,4);(5,6);(7,8)]
Someone can help me? I was thinking about this function but it doesn't work:
let cut x = function
[] -> []
| (a,b) -> []
| (a,b)::ris -> ris
Just remember, that
let f x y = function -> <code>
is really a shortcut (or a syntactic sugar), for:
let f x y z = match z with -> <code>
So, it just cuts the last argument in a function, and automatically matches on it.
Also, when you pattern matching keep in mind, that all expressions in the left side of pattern match should have the same type. Otherwise, compiler may pick a random one, and decide, that all others have the same type, yielding a somewhat confusing error message. The same is true for the right sides of patter match. So, when you see a compiler message, saying that something is not what he has expected, just check this preconditions:
| [] (* is a list, by definition *)
| (a,b) -> [] (* is a pair, by definition of a pair *)
| (a,b)::ris -> ris (* is a list, by definition of (::) *)
If left part works, look at the right.
Also, if you have a variable that you do not need to use, then you should better give it a name starting with underscore, or just an underscore.
let cut = function
| [] -> []
| _::xs -> xs
You are almost there:
let tl x = match x with
| [] -> [] (* or failwith "empty" *)
| ab::ris -> ris
Few points:
function takes another argument. Your function already get one arg, so use match x with instead.
You are interested only in the list is empty or has a "tail", so you need not pattern-match its element as a tuple.
This function is called "tail", in OCaml, known as List.tl.
You could write simple:
let cut = List.tl
You have little mistake.
Third line should look like
| [(a,b)] -> []
or
| (a,b) :: [] -> []
P.S. by the way, this third line is unnecessary. Just remove it.
And delete x in first line:
let cut = function
I am trying to implement something like a pipe function.
Input: a list of functions
Output: a function
Example:
# pipe [(fun y -> y+5);(fun y -> y*3)] 1 = 18
# pipe [(fun z -> z*3);(fun z -> z+5)] 1 = 8
My problem:
A helper function composite takes two arguments, which are a function f and a list of function l. If the list is empty, it returns the function f.
If it is not, f will be an argument of the head of list g.
However, I got a syntax error. I don't figure out what's going on.
Has anyone found an error?
let pipe l =
let composite f l = match l with
[]->f
| g::gs -> (fun h -> (g -> f)) in
List.fold_left composite (fun x -> x) l
(fun h -> (g -> f)) is not syntactically correct, and I'm not sure what it is supposed to mean.
The pattern-matching of your composite function looks like what you would write for a recursive function, but then you're trying to define it non-recursively for use with fold_left. Either way would be good, but you need to make up your mind, because here you've a sad compromise that does not work.
I'm trying to write a simple recursive function that look over list and return a pair of integer. This is easy to write in c/c++/java but i'm new to ocaml so somehow hard to find out the solution due to type conflict
it should goes like ..
let rec test p l = ... ;;
val separate : (’a -> bool) -> ’a list -> int * int = <fun>
test (fun x -> x mod 2 = 0) [-3; 5; 2; -6];;
- : int * int = (2, 2)
so the problem is how can i recursively return value on tuple ..
One problem here is that you are returning two different types: an int for an empty list, or a tuple otherwise. It needs to be one or the other.
Another problem is that you are trying to add 1 to test, but test is a function, not a value. You need to call test on something else for it to return a value, but even then it is supposed to return a tuple, which you can't add to an integer.
I can't figure out what you want the code to do, but if you update your question with that info I can help more.
One guess that I have is that you want to count the positive numbers in the list, in which case you could write it like this:
let rec test l =
match l with [] -> 0
| x::xs -> if x > 0 then 1 + (test xs)
else test xs;;
Update: since you've edited to clarify the problem, modify the above code as follows:
let test l =
let rec test_helper l pos nonpos =
match l with [] -> (pos, nonpos)
| x::xs -> if x > 0 then test_helper xs 1+pos, nonpos
else test_helper xs pos 1+nonpos
in test_helper l 0 0;;
Using the accumulators help a lot in this case. It also makes the function tail-recursive which is always good practice.
Been away from OCaml for a bit, but I think this will do the trick in regards to REALFREE's description in the comment
let rec test l =
match l with
[] -> (0,0)
| x::xs ->
if x > 0 then match (test xs) with (x,y) -> (x+1, y)
else match (test xs) with (x,y) -> (x, y+1);;
You can used the nested match statements to pull out pieces of the tuple to modify
EDIT:
I didn't know about the syntax Pascal Cuoq mentioned in his comment below, here's the code like that, it's neater and a little shorter:
let rec test l =
match l with
[] -> (0,0)
| x::xs ->
if x > 0 then let (x,y) = test xs in (x+1, y)
else let (x,y) = test xs in (x, y+1);;
But the accepted answer is still much better, especially with the tail recursion ;).