Trying to call function i-times in OCaml with a for cycle - ocaml

I have been trying to create a cycle to call an changing function i-times , but for some reason the cycle itself always spits out an error. I have also tried an recursive function to call itself but didn't work either.
Is it even possible to make it work with for`s.
r is a list of lists.
a and b are two immutable variables.
(List.nth (r) (i)) gives an list.
let rec changing (lista: 'a zlista) (a:int) (b:int) =
match lista with
| Vazio -> failwith "NO"
| Nodo (n, l, r) ->
if a <= n && n <= b then n
else if a < n && b < n then changing l a b
else changing r a b
let rec call_changing (a: int) (b: int) =
for i=0 to ort do
changing (List.nth (r) (i)) (a) (b)
done;;

Changing returns an int, in order to call it in a for loop you have to ignore the result of the function :
for i = 0 to ort do
let _ = changing .... in ()
done
(* Or *)
for i = 0 to ort do
ignore (changing ....)
done
EDIT :
If you want to print the result you can do :
for i = 0 to ort do
Printf.printf "Result for %d iteration : %d\n" i (changing ....)
done
See the Printf documentation for more information

To perhaps generalize on Butanium's answer, OCaml is not a pure functional programming language. It does contain imperative features. Imperative features are all about side-effects. Functions which exist for the purpose of their side-effects on the system (like Printf.printf) by convention return () (the literal for the unit type).
A for loop is an imperative feature. As such, it expects that any expression (or expessions chained with ;) contained within will return unit. If they do not, you will receive warnings.
The for loop expression itself (for ... = ... to ... do ... done) returns unit so the warning can clue you in that any code in the loop which does not have side-effects is inconsequential, and while your code will compile and run, it may not do what you expect.
As a side note, I believe you may be a little overzealous with the parentheses, likely making your code harder to read.
let rec call_changing (a: int) (b: int) =
for i=0 to ort do
changing (List.nth (r) (i)) (a) (b)
done;;
Properly indented and with extraneous parens removed:
let rec call_changing (a: int) (b: int) =
for i=0 to ort do
changing (List.nth r i) a b
done;;

Related

Remove Warning this expression should have type unit in Ocaml

Why am I getting Warning this expression should have type unit with this code? although it does what it should do.
let matchInf42 list =
let a = ref 0 in
let lstLength = List.length list in
let rec matchInf4242 list =
match list with
|[]->[]
|m::body->
begin
if (m < 42) then a := !a + 1;
matchInf4242 body
end
in matchInf4242 list;
if(!a = lstLength) then -1 else 0
Warning:
ocamlopt match.ml -o m
File "match.ml", line 14, characters 7-24:
14 | in matchInf4242 list;
^^^^^^^^^^^^^^^^^
Warning 10: this expression should have type unit.
TL;DR: The error you obtain is a typical type error (mostly)
"Mostly" because, admittedly, it is not an "error" but a mere "warning" here, yet it appears this kind of warning (Warning 10: non-unit-statement) is always worth being addressed (i.e., avoided).
It is actually an instance of the following pattern:
42; print_string "…" ;;
(* or more generally *)
any_value_not_having_type_unit; any_value_having_type_unit ;;
(* which would raise *)
> Characters 0-2:
> 42; print_string "…";;
> ^^
> Warning 10: this expression should have type unit.
> …- : unit = ()
Further details
Just to recall, unit is a singleton type (which only has the value ()) and is typically chosen to assign a return type to functions that "return no specific value" but produce some side-effect.
Actually, the sequence operator is "a bit more general / more flexible" as what we might expect:
# let semicolon i j = i; j ;;
val semicolon : 'a -> 'b -> 'b = <fun>
That is to say, it's not semicolon : unit -> 'b -> 'b, and thereby the message we got for the code i; j when i does not have the type unit, is a mere warning, not a type error.
Fixes/workarounds
Two strategies to avoid this warning:
Either ignore it by relying on the ignore function
# ignore;;
- : 'a -> unit = <fun>
# ignore 42; print_string "…";;
…- : unit = ()
Or change/fix the way you compute the left-hand side of the sequence (so its type is unit).
In the particular case of your question example, it would suffice to write this (the only change being indicated with a symbol §):
let matchInf42 list =
let a = ref 0 in
let lstLength = List.length list in
let rec matchInf4242 list =
match list with
|[] -> () (*←§*)
|m::body->
begin
if (m < 42) then a := !a + 1;
matchInf4242 body
end
in matchInf4242 list;
if(!a = lstLength) then -1 else 0
Extra remark
Finally for completeness (even though it was not explicitly part of your question), note that the example function you considered could also be implemented in a more "functional" style (without references nor sequences, avoiding also the need for calling the List.length function beforehand):
let matchInf42 l =
if List.for_all (fun m -> m < 42) l
then -1 else 0
(* or *)
let matchInf42 l =
if List.fold_left (fun r e -> r && e < 42) true l
then -1 else 0
Change
matchInf4242 list
to either
ignore (matchInf4242 list)
or
matchInf4242 list in ().
This makes the statement return () (i.e. a unit), which is what ocaml expects.

Minimum of a list

I want to create a non-recursive function for my minimum
but I have some troubles with it
Can you help me please.
`let min_list lst=
let n=list.length lst ;;
let a=list.nth lst ;;
for i = 1 to n-1 ;;
let b=list.nth lst i;;
if a >b then a=b lst done ;;`
Honesly,It's difficult with non recursive fonction.So this is just for learning.I still have erreur in ligne 6
let min_list lst=
let a=List.hd lst in
let n=List.length lst in
for j =1 to n-1 do
let b=List.nth lst j in
if a > b then (let a=b) done ;;
Thank you it's useful It help me a lot .I have one other question what the difference between this
let min_array a =
let min =ref (List.hd a) in
for i = 1 to List.length a -1 do
if List.nth a i < !min then min := List.nth a i
done;
!min;;
print_int (min_array [ 10 ; 5 ; 7 ; 8 ; 12 ]);;
and
let min_array a =
let min =ref (List.hd a) in
for i = 1 to List.length a -1 do
if ref (List.nth a i) < min then min := List.nth a i
done;
!min;;
print_int (min_array [ 10 ; 5 ; 7 ; 8 ; 12 ]);;
It's the same ?I think
Why don't you want to use a recursive function ?
Liste are made to be crossed by recursive function. Everytime you use List.nth l n Ocaml has to cross n values until he found the nth element.
In Ocaml you can't change variable value as you do in other languages. You want a to be a ref.
Also your function won't return anything you'll have to put a !a between the done and the ;;. There will be a ! Because a will be a ref.
But if you want to practice use arrays instead because what you do here is in complexity O(n²) instead of O(n).
As said in the answer from Butanium, this kind of non-recursive function might be more relevant with arrays. And to work with mutable values, you need to use a reference.
A solution might then be something like (without dealing with case of an empty array):
let min_array a =
let min = ref a.(0) in
for i = 1 to Array.length a -1 do
if a.(i) < !min then min := a.(i)
done;
!min
The last line is important here, because it gets the value to be returned by the function.
Can then be used like that:
# min_array [| 10 ; 5 ; 7 ; 8 ; 12 |];;
- : int = 5
If you really do want to use lists instead of arrays, just use List.nth a i instead of a.(i) and List.length instead of Array.length.
Edit after question update
As Shawn and Jeffrey Scofield said in their respective comment, you should try to understand a bit better OCaml's syntax. And please don't use ;; in your programs, just keep it for the REPL.
As described in the documentation,
ref returns a fresh reference containing the given value.
Which means that when you write ref (List.nth a i) < min,
you create a fresh reference containing the i-th value the list, then compare it to min (which is also a reference). Luckily, mutable structures are compared by contents, which means that OCaml will access to your fresh reference's value, then access to min's value, and compare them. Thus, it will produce the same result as the direct comparison List.nth a i < !min, with a bit of useless memory allocation/access.
You can do this quite concisely by taking advantage of some features of the OCaml stdlib:
(* 'a list -> 'a option *)
let min_list l =
if List.length l > 0 then
Some (List.fold_left min (List.hd l) l)
else
None
Thanks to the min built-in, this works for lists of any type.
e.g. in a utop shell we can see:
min_list [99; 33; -1];;
- : int option = Some (-1)
min_list [99.1; 33.2; -1.3];;
- : float option = Some (-1.3)
min_list ["z"; "b"; "k"];;
- : string option = Some "b"
Explanation
First we recognise that the list may be empty, in which case we cannot return a meaningful value. This implies the function should return an option type, so either Some <value> or None.
Next we can use List.fold_left to iterate through the list.
Unfortunately the docs for List.fold_left are almost completely unhelpful:
val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a
fold_left f init [b1; ...; bn] is f (... (f (f init b1) b2) ...) bn.
It's as if they assume that if you're using OCaml you're already an elite master of functional programming, who naturally knows what a "fold left" does.
I'm not an elite master of functional programming, but I've been around long enough to know that fold_left is basically the same as the reduce function in Python.
It's a function that iterates through a list, applies a function to each value as it goes, and returns a single value.
So we can start to make sense of the signature of fold_left...
It takes three arguments:
The first arg, f, is a function which itself takes two args - the first or 'left' arg is the 'accumulated' value, and the second arg is the current value from the list as we iterate through. Whatever value you return from this function will be passed back into it as the left 'accumulated' value on the next iteration. When the list is exhausted the accumulated value will be returned from fold_left.
The second arg, init is an initial value. It is passed to f as the left 'accumulated' arg in the first step, when nothing has been otherwise accumulated yet.
Third arg is our list of values
So when we return:
Some (List.fold_left min (List.hd l) l)
...we are passing the min function as f and (List.hd l) as init.
List.hd l just returns the first element of the list l. We could use any element from the list as an initial value, but List.hd exists and gives us the first.
So fold_left is going to iterate through the list and f will return min <accumulated> <current>. So at each iteration step the accumulated value passed forward is the lowest value seen so far.
Non-recursive?
I did wonder if perhaps the fold_left method does not count as non-recursive somehow, since no one else had suggested it. Even though we have not used let rec anywhere, maybe somewhere internally it is secretly recursive?
For fun I decided to try writing the reduce/fold function from scratch:
let reduce f init l =
let acc = ref init in
List.iter (fun el -> acc := f !acc el) l;
!acc
(* we can directly substitute `reduce` for `List.fold_left` *)
let min_list l =
if List.length l > 0 then
Some (reduce min (List.hd l) l)
else
None
...again, no let rec needed so I guess it counts as non-recursive.

Im trying to add a tuple to a list on Ocaml

Im trying to add a tuple of type (int*int) on a for cycle to a list but i get an error saying : this expression should have type unit.
this is what i have right now:
let addtuple k lst =
for i=0 to k - 1 do
let (n,j) =Scanf.scanf " %d %d" (fun a b->(a,b))
in
(n,j)::lst
done;;
The purpose of the OCaml for is to do something, rather than compute a value. So the body of the loop should be an OCaml expression that has a useful side effect (like printing a value). For this reason, the body of a for loop should have the type unit, the type used for expressions that don't have an interesting value. But your loop has a body that is a list. The compiler is telling you (correctly) that this indicates that something is wrong.
Your code is written assuming that the expression (n, j) :: lst will change the value of lst. But this is not the case. In a functional language like OCaml, you can't change the values of variables.
If your function is supposed to return a list, it can't be based on a for loop, which always returns () (the unique value of type unit). Most likely it should be based on a fold (which accumulates a value while working through a series of inputs) or on your own recursive function.
With a for you need to use ref:
let addtuple k lst =
let r = ref lst in
for i = 1 to k do
r := (Scanf.scanf " %d %d" (fun x y -> (x, y))) :: !r
done;
!r;;
A more functional approach using a recursive function:
let rec addtuple k lst =
match k with
| 0 -> lst
| _ -> addtuple (k - 1) ((Scanf.scanf " %d %d" (fun x y -> (x, y))) :: lst);;

OCaml variable counting

I am trying to achieve the following: Finding the element at a specific index.
So if I had a list of [5; 2; 3; 6] and ask for the element at index 2, it would return 3.
let counter = 0;;
let increase_counter c = c + 1;;
let rec get_val x n = match x with
[] -> -1
| (h::t) ->
if (counter = n) then
h
else
increase_counter counter ; get_val t n
;;
But this code is giving me a bug saying that -1 is not of type 'unit'?
As Jeffrey Scofield said, you should write let counter = ref 0 to make counter mutable. Now, you can use the built in incr function to increment it (equivalent to counter := !counter + 1), and you'll get its value with !counter.
There is also a problem in your algorithm : if the counter is equal to n, you return the head of the list... you mean : if the head of the list is equal to n, you return the counter.
Your program is then :
let counter = ref 0;;
let rec get_val x n = match x with
[] -> -1
| (h::t) ->
if (h = n) then
!counter
else
begin incr counter ; get_val t n end
;;
Note that I've added begin and end around the else block so it can be interpreted as a sequence of instructions.
Your program now works, but it is not the best way to solve this problem with ocaml.
You should write something like
let get_val x n =
let rec get_val_aux x n counter = match x with
| [] -> -1
| h :: _ when h = n -> counter
| _ :: t -> get_val_aux t n (succ counter)
in
get_val_aux x n 0
;;
Here, we add a parameter to the get_val_aux function which we increment at each call. This function is nested within the get_val function to hide this additional parameter which is initialized with 0 on the first call.
Instead of using an if statement, we use the when condition to know when the element has been found, and add a new case to match the last case (not found). Note the use of the _ wildcard to avoid an unused variable.
The succ function (for successor) only adds 1 to its parameter. It is equivalent to counter + 1.
There are many problems with this code. If you ignore your immediate problem for a moment, you are treating OCaml variables like the variables of an imperative language. However, OCaml variables are immutable. This function
let increase_counter c = c + 1
Doesn't change the value of any variable. It just returns a number 1 bigger than what you give it.
The only error I get from the toplevel when I enter your code is for this expression:
increase_counter counter ; get_val t n
The compiler is warning you that the expression before ; is supposed to be executed for its side effects. I.e., it should almost always have type unit. Since (as I say) your function increase_counter returns an int, the compiler is warning you about this.

number_in_month exercise (Iteration over multiple lists in SML)

I am having two lists in SML, lets say list A [(a,b,c),(d,e,f)] and list B [b,e]. I want to count how many occurrence of each item in B that matches the second element of each triple in A. The output should be 2. Because b and e each occurs once in A.
This is my code so far but my counter is always set to 0 when I move from one element to another in B. I know in Java this will just be a simple double for loop.
fun number_in_months (d : (int * int * int ) list, m : (int) list) =
if null m then 0
else if null d then number_in_months(d, tl m)
else if (#2(hd d)) = (hd m) then 1 + number_in_months (tl d, m)
else number_in_months(tl d, m)
The code is not accumulating a value between recursive calls. There may be other logic errors too.
Accumulating a value using recursion and functions is a common pattern which you can read more about here. It's essence is to deconstruct a list using head and tail until the list is empty and accumulate some value at each call. The sum function below is a simple example to show this. This could be adapted to your example to accumulate acc when b or e are found in list A.
fun sum(numbers: (int) list) =
let fun sumR(numbers: (int) list, acc: int) =
if null numbers
then acc
else
sumR(tl numbers, hd numbers + acc)
in
sumR(numbers, 0)
end
Running on [1,2,3] gives:
val sum = fn : int list -> int
- sum([1,2,3]);
val it = 6 : int
Note I am intentionally vague with this answer since this is a question regarding Coursera homework for the Programming Languages class.
As you mention, it would be a nested/double loop in any imperative programming language. What you are actually missing is the second loop.
Your "inner" loop goes through all elements of d, and when this is done, your "outer" loop tries to pop the top element of m and start all over, as seen from this line of your code:
else if null d then number_in_months(d, tl m)
However as you can see, you have just tested the list d to be empty and you supply this (exact same list) to your recursive call on the tail of m, which will then fall in this same case for each successive call until m is also empty and you return 0.
Thus what you are missing is to "keep a copy" of the original input list m. This can be done in various ways, but an inner (helper) function is properly the most used one and it even "looks" like a nested loop
fun number_in_months (d, m) =
let
fun nim' ([], y::ys) = nim (d, ys) (* 1 *)
| nim' (_, []) = 0 (* 2 *)
| nim' ((_, x2, _) :: xs, yss as (y::ys)) = ... (* 3 *)
in
nim'(d, m)
end
Using pattern matching the above code gets much simpler and less error prone. In case 1, the "inner" loop has gone through all elements in d, thus the recursive call using d from the outer function which is not changed at any time. In case 2, the "outer" loop has gone through all elements of m and we return 0 (the neutral element of addition). In case 3 we do the actual work. Here pattern matching is used such that we don't need to enforce the type of the argument and we don't need to pull out the 2nd element of the triple, we already have it in the variable x2. All that is needed is to do the computation and make a recursive call with xs and yss.
When doing it this way, the inner (helper) function is using a "copy" of the original input list d and stepping through its elements (potentially modifying it), but we always got a reference to the original input list, which we can use if/when needed.