I have the following function :
let extract n l =
let rec aux acc pro = function
|[] -> acc
|a::b -> if (List.length pro) = n then aux (pro::acc) [] (a::b) else aux acc (a::pro) b; aux acc (pro) b
in aux [] [] l
As you can see in my pattern matching at the second test's case I am calling two times the function. Is it possible ?
So it is possible to have this kind of function :
let rec some_function = function
| [] ->[]
| a::b -> some_function b; some_function b (*so I am calling two times the function in a single test*)
I am asking this question because here I have the following warning :
File "main.ml", line 4, characters 48-72:
Warning 10: this expression should have type unit.
So there is a problem at the exact place I called two times my recursive function.
It might be because I am using ; but in this case how could I seperate these two calls ?
Thank you !
To add onto FlorianWeimer's answer, some information about your error message.
Warning 10: this expression should have type unit.
OCaml is strongly typed. Therefore, if a function returns, say, an integer or a list, and you don't do anything with it, it'll wonder what's going on and warn you.
A function call like print_int 5; returns (), which is of type unit. That basically means that it returns nothing because you're not calling it to compute something, but to do something. It has done that thing and now it returns and you move on.
But a function call like float_of_int 5;, that returns a value (the float 5.0). You (probably) didn't call it to do something, but to compute something, and what it returns is what interests you. Same goes for arithmetic expressions like 3+6; or for straight up values like 10; or "abc"; or [];.
That's why, if you write one of these things that have a value and you don't use that value (in an assignment, or as a parameter of another function), OCaml warns you. It tells you "I computed something that I didn't assign, didn't return, and didn't use as the argument of something else. Usually, things of type unit are the only things like that. Are you sure you don't have a bug in your code?"
Sometimes you know what you're doing and you don't want that warning. In that case, you can call the ignore function. ignore will take anything and ignore it, returning (). For instance, ignore 5; or ignore (float_of_int 10); won't throw the "this expression should have type unit" warnings that you'd get with 5; or float_of_int 10;.
It is possible in the sense that the compiler accepts it, but it only makes sense if you do something with the result (or the function has a side effect). The classic example for two function calls is the recursive computation of the Fibonacci sequence:
let rec fib = function
| 0 -> 0
| 1 -> 1
| n -> fib (n - 1) + fib (n - 2)
Related
I want to convert a sequence to a list using List.init. I want at each step to retrieve the i th value of s.
let to_list s =
let n = length s in
List.init n
(fun _i ->
match s () with
| Nil -> assert false
| Cons (a, sr) -> a)
This is giving me a list initialized with the first element of s only. Is it possible in OCaml to initialize the list with all the values of s?
It may help to study the definition of List.init.
There are two variations depending on the size of the list: a tail recursive one, init_tailrec_aux, whose result is in reverse order, and a basic one, init_aux. They have identical results, so we need only look at init_aux:
let rec init_aux i n f =
if i >= n then []
else
let r = f i in
r :: init_aux (i+1) n f
This function recursively increments a counter i until it reaches a limit n. For each value of the counter that is strictly less than the limit, it adds the value given by f i to the head of the list being produced.
The question now is, what does your anonymous function do when called with different values of i?:
let f_anon =
(fun _i -> match s () with
|Nil -> assert false
|Cons(a, sr) -> a)
Regardless of _i, it always gives the head of the list produced by s (), and if s () always returns the same list, then f_anon 0 = f_anon 1 = f_anon 2 = f_anon 3 = hd (s ()).
Jeffrey Scofield's answer describes a technique for giving a different value at each _i, and I agree with his suggestion that List.init is not the best solution for this problem.
The essence of the problem is that you're not saving sr, which would let you retrieve the next element of the sequence.
However, the slightly larger problem is that List.init passes only an int as an argument to the initialization function. So even if you did keep track of sr, there's no way it can be passed to your initialization function.
You can do what you want using the impure parts of OCaml. E.g., you could save sr in a global reference variable at each step and retrieve it in the next call to the initialization function. However, this is really quite a cumbersome way to produce your list.
I would suggest not using List.init. You can write a straightforward recursive function to do what you want. (If you care about tail recursion, you can write a slightly less straightforward function.)
using a recursive function will increase the complexity so i think that initializing directly the list (or array) at the corresponding length will be better but i don't really know how to get a different value at each _i like Jeffrey Scofield said i am not really familiar with ocaml especially sequences so i have some difficulties doing that:(
I try to define function with the following protocol:
[(1,2), (6,5), (9,10)] -> [3, 11, 19]
Here is what I have now:
fun sum_pairs (l : (int * int) list) =
if null l
then []
else (#1 hd(l)) + (#2 hd(l))::sum_pairs(tl(l))
According to type checker I have some type mismatch, but I can't figure out where exactly I'm wrong.
This code runs in PolyML 5.2:
fun sum_pairs (l : (int * int) list) =
if null l
then []
else ((#1 (hd l)) + (#2 (hd l))) :: sum_pairs(tl l)
(* ------------^-------------^ *)
The difference from yours is subtle, but significant: (#1 hd(l)) is different from (#1 (hd l)); the former doesn't do what you think - it attempts to extract the first tuple field of hd, which is a function!
While we're at it, why don't we attempt to rewrite the function to make it a bit more idiomatic? For starters, we can eliminate the if expression and the clunky tuple extraction by matching on the argument in the function head, like so:
fun sum_pairs [] = []
| sum_pairs ((a, b)::rest) = (a + b)::sum_pairs(rest)
We've split the function into two clauses, the first one matching the empty list (the recursive base case), and the second one matching a nonempty list. As you can see, this significantly simplified the function and, in my opinion, made it considerably easier to read.
As it turns out, applying a function to the elements of a list to generate a new list is an incredibly common pattern. The basis library provides a builtin function called map to aid us in this task:
fun sum_pairs l = map (fn (a, b) => a + b) l
Here I'm using an anonymous function to add the pairs together. But we can do even better! By exploiting currying we can simply define the function as:
val sum_pairs = map (fn (a, b) => a + b)
The function map is curried so that applying it to a function returns a new function that accepts a list - in this case, a list of integer pairs.
But wait a minute! It looks like this anonymous function is just applying the addition operator to its arguments! Indeed it is. Let's get rid of that too:
val sum_pairs = map op+
Here, op+ denotes a builtin function that applies the addition operator, much like our function literal (above) did.
Edit: Answers to the follow-up questions:
What about arguments types. It looks like you've completely eliminate argument list in the function definition (header). Is it true or I've missed something?
Usually the compiler is able to infer the types from context. For instance, given the following function:
fun add (a, b) = a + b
The compiler can easily infer the type int * int -> int, as the arguments are involved in an addition (if you want real, you have to say so).
Could you explain what is happening here sum_pairs ((a, b)::rest) = (a + b)::sum_pairs(rest). Sorry for may be dummy question, but I just want to fully understand it. Especially what = means in this context and what order of evaluation of this expression?
Here we're defining a function in two clauses. The first clause, sum_pairs [] = [], matches an empty list and returns an empty list. The second one, sum_pairs ((a, b)::rest) = ..., matches a list beginning with a pair. When you're new to functional programming, this might look like magic. But to illustrate what's going on, we could rewrite the clausal definition using case, as follows:
fun sum_pairs l =
case l of
[] => []
| ((a, b)::rest) => (a + b)::sum_pairs(rest)
The clauses will be tried in order, until one matches. If no clause matches, a Match expression is raised. For example, if you omitted the first clause, the function would always fail because l will eventually be the empty list (either it's empty from the beginning, or we've recursed all the way to the end).
As for the equals sign, it means the same thing as in any other function definition. It separates the arguments of the function from the function body. As for evaluation order, the most important observation is that sum_pairs(rest) must happen before the cons (::), so the function is not tail recursive.
I am reading the book by jason and do not quite understand the following program:
let fact2 i =
let rec loop accum i =
if i = 0 then
accum
else
loop (i * accum) (i - 1)
in
loop 1
How is accum initialized?
What is the meaning of the last two lines (i.e. in loop 1)? loop has two parameters. why only one is passed here (i.e. loop 1).
Thank you very much!!!
I think that it's a mistake in implementation. Last line should be
loop 1 i
Integer 1 initialises accum from loop function and i initializes i in the same function.
Note that the lines starting with let rec loop accum i define a function. So accum is initialized when the function is called. This happens in the last line. As Kakadu points out, there's a transcription error in your post. The last line should say loop 1 i which (in essence) initializes accum to 1.
I think you have an extra "i" in the first line. That makes fact2 take an extra argument which is never used. Instead it should read:
let fact2 =
The last line that says "loop 1" is often called a partial application.
Ocaml usually uses curried functions, so another way of thinking of it is that loop actually takes one parameter and returns a function which in turn takes another parameter and returns an int.
In this particualar case, the type of (loop 1) is int -> int meaning it takes an int and returns an int. The type of loop is int -> int -> int meaning it takes an int and return an int -> int. It can also be written more explicitly as int -> (int -> int) since -> is right-associative.
To answer the other question, accum is initialized by passing 1 to loop.
Here is more information on currying: http://en.wikipedia.org/wiki/Currying
And of course, adding another "i" as others are suggesting would also work, but then you'd still be confused when others left it out.
It may help to think of let f x y = ... as being equivalent to let f = fun x -> fun y -> ...
And of course let f x = g x is the same as let f = g except the former will only work when g is a function.
I am new to OCaml, so I am learning the basics. I am writing a function that determines whether a list contains a given integer.
let rec int_member (x: int) (l: int list) : bool
begin match l with
| [] -> false
| hd :: rest -> x = hd || int_member rest x
end
as a test case...
let test (): bool =
(int_member 1 [1;2;3]) = true
;; run_test "contains 1 [1;2;3]" test
I am getting an error saying that "this expression has type int list but an expression was expected of type int". How can I fix this?
If you look at your recursive call, you should see that you're not passing the arguments quite right! Otherwise this code is quite good. (I see a missing =, and also using begin and end isn't very idiomatic OCaml here. You can just leave them out.)
int_member rest x
The first argument to int_member should be an int. You're passing an int list as the first argument. That's what the error message is complaining about.
You simply switched around the order of the arguments.
PS: The begin ... end in your code is superfluous.
I need a function that recursively returns (not prints) all values in a list with each iteration. However, every time I try programming this my function returns a list instead.
let rec elements list = match list with
| [] -> []
| h::t -> h; elements t;;
I need to use each element each time it is returned in another function that I wrote, so I need these elements one at a time, but I can't figure this part out. Any help would be appreciated.
Your function is equivalent to :
let rec elements list =
match list with
| [] -> []
| h :: t -> elements t
This happens because a ; b evaluates a (and discards the result) and then evaluates and returns b. Obviously, this is in turn equivalent to:
let elements (list : 'a list) = []
This is not a very useful function.
Before you try solving this, however, please understand that Objective Caml functions can only return one value. Returning more than one value is impossible.
There are ways to work around this limitation. One solution is to pack all the values you wish to return into a single value: a tuple or a list, usually. So, if you need to return an arbitrary number of elements, you would pack them together into a list and have the calling code process that list:
let my_function () = [ 1 ; 2; 3; 4 ] in (* Return four values *)
List.iter print_int (my_function ()) (* Print four values *)
Another less frequent solution is to provide a function and call it on every result:
let my_function action =
action 1 ;
action 2 ;
action 3 ;
action 4
in
my_function print_int
This is less flexible, but arguably faster, than returning a list : lists can be filtered, sorted, stored...
Your question is kind of confusing - you want a function that returns all the values in a list. Well the easiest way of returning a variable number of values is using a list! Are you perhaps trying to emulate Python generators? OCaml doesn't have anything similar to yield, but instead usually accomplishes the same by "passing" a function to the value (using iter, fold or map).
What you have currently written is equivalent to this in Python:
def elements(list):
if(len(list) == 0):
return []
else:
list[0]
return elements(list[1:])
If you are trying to do this:
def elements(list):
if(len(list) > 0):
yield list[0]
# this part is pretty silly but elements returns a generator
for e in elements(list[1:]):
yield e
for x in elements([1,2,3,4,5]):
dosomething(x)
The equivalent in OCaml would be like this:
List.iter dosomething [1;2;3;4;5]
If you are trying to determine if list a is a subset of list b (as I've gathered from your comments), then you can take advantage of List.mem and List.for_all:
List.for_all (fun x -> List.mem x b) a
fun x -> List.mem x b defines a function that returns true if the value x is equal to any element in (is a member of) b. List.for_all takes a function that returns a bool (in our case, the membership function we just defined) and a list. It applies that function to each element in the list. If that function returns true for every value in the list, then for_all returns true.
So what we have done is: for all elements in a, check if they are a member of b. If you are interested in how to write these functions yourself, then I suggest reading the source of list.ml, which (assuming *nix) is probably located in /usr/local/lib/ocaml or /usr/lib/ocaml.