I am new to OCaml. I am trying to use List.nth just like List.length but it keeps giving me a syntax error or complains about not matching the interface defined in another file. Everything seems to work fine if I comment out using List.nth
Thanks
It's hard to help unless you show the code that's not working. Here is a session that uses List.nth:
$ ocaml
OCaml version 4.00.0
# let x = [3;5;7;9];;
val x : int list = [3; 5; 7; 9]
# List.nth x 2;;
- : int = 7
#
Here's a session that defines a function that uses List.nth. (There's nothing special about this.)
# let name_of_day k =
List.nth ["Mon";"Tue";"Wed";"Thu";"Fri";"Sat";"Sun"] k;;
val name_of_day : int -> string = <fun>
# name_of_day 3;;
- : string = "Thu"
#
(As a side comment: using List.nth is often inappropriate. It takes time proportional to n to find the nth element of a list. People just starting with OCaml often think of it like accessing an array--i.e., constant time--but it's not.)
Related
I have a list with two items, say [1;2]. I try to extract second item by this code.
let _::b::_ = [1;2] in b
Compiler gives warning Warning 8: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: (_::[]|[])
Though it's sensible, I would rather like to know how can we do better. May there be without warning?
This is a downside of OCaml's exhaustiveness checking for patterns. In almost all cases it's incredibly useful, but in a few cases you'd like to use a pattern that isn't exhaustive. I.e., in cases where you know the possible values are limited in some way.
If you're absolutely positive your list has at least 2 elements you can use List.nth:
# List.nth [1; 2] 1;;
- : int = 2
However this only works for extracting one value from a list, not in general.
You can turn off the exhaustiveness warning:
# let [#warning "-8"] _ :: b :: _ = [1; 2] in b;;
- : int = 2
You can write an exhaustive pattern, which is what I usually do myself:
# match [1; 2] with
| _ :: b :: _ -> b
| _ -> assert false ;;
- : int = 2
I am a beginner with OCaml. I would like to skip the first element of my list.
Here is my list:
let l = [1;2;3;4;5;6;7;2;1];;
I want to use this in my FOR:
let l = List.tl l;
here is my full code:
let l = [1;2;3;4;5;6;7;2;1];;
let n = 1;;
let counter = ref 0;;
for i = 0 to (List.length l) do
if List.hd l = n then counter := !counter + 1;
print_int(!counter);
print_string("\n");
let l = List.tl l
done;;
But I have errors in the DONE and it says syntax error.
Can anyone help me please?
Your problem is that let always requires a matching in. The full expression looks like this:
let var = expr1 in expr2
Since you're missing the in part, you get a syntax error.
However, the deeper problem is that you're trying to modify the value of l. The way you have defined l, it's immutable. You can't change its value. If you want to be able to change its value you can define it as a reference, as you have done for counter.
(There is another form of let used at the top level of a module. This form doesn't have a matching in. But your code isn't defining a top-level name, so this is not relevant.)
I have declared a list l=[];; and now trying to append tuples into this list using '#'. But I am not able to do so. Can anyone please help me sorting this out.
let l = []
for x = 1 to 10 do
l <- l#[(x,x+10)]
done;;
And want final answer as: l=[(1,10),(2,20),(3,30).....]
Your definition of l means that l is immutable. You define its value as [], and this can never be changed.
If you want to be able to change l, you need to define it as a mutable value. One simple way to do this is to make it a "ref":
# let l = ref [];;
val l : '_a list ref = {contents = []}
After this you can get the value of l with the ! operator and change the value using the := operator:
# !l;;
- : '_a list = []
# l := !l # [3];;
- : unit = ()
# !l;;
- : int list = [3]
However, this code is not idiomatic OCaml. If you're studying OCaml academically, it might be better to learn to work with immutable values.
Update
Here are some hints on writing recursive functions. I don't want to spoil the exercise by writing the code for you.
The way to solve a problem recursively is to answer questions like this:
What general problem am I trying to solve? In your case, you're trying to create a list of pairs of some length with some arithmetic properties.
What is the most trivial case of this problem? In your case, the most trivial case is when the desired length is 0 (in which case the list is empty).
If I have a non-trival case of the problem, how can I break it into easily calculated answers and smaller cases of the same problem? You want to assemble these into the full answer. In your case, the smaller pieces would be the first element of the result (easily calculated), and a list that's one shorter (smaller case of the same problem).
Then your code looks like this for the garden variety recursive function with some number of parameters (say a, b, c, d):
let rec f a b c d =
if <<this is the trivial case>> then
<<the answer is obvious>>
else
let tp = <<answer to tiny piece of the problem>> in
let (a', b', c', d') = <<rest of the problem (smaller)>> in
let smres = f a' b' c' d' in
<<combine tp and smres>>
I would like to understand how sequential composition works much better than I do now in SML. I have to write a program that takes a list of integers and moves the integer at index zero to the last index in the list. ie. [4, 5, 6] -> [5, 6, 4].
The code I have right now is:
- fun cycle3 x =
= if length(x) = 1 then x
= else (List.drop(x, 1);
= x # [hd(x)]);
val cycle3 = fn : 'a list -> 'a list
The question lies in my else statement, what I want to happen is first concatenate the first term to the end, and then second drop the first term. It seems simple enough, I just don't understand how to perform multiple functions in a particular order using SML. My understanding was that the first function called has the scope of the second function that would have the scope of the third function.. etc etc.. What am I doing wrong here?
Most things in SML are immutable -- your function, rather than modifying the list, is building a new list. List.drop(x,1) evaluates to a new list consisting of all but the first element of x, but does not modify x.
To use your method, you would bind the result of List.drop(x,1) to a variable, as in the following:
fun cycle3 x = if length x = 1
then x
else let
val y = List.drop(x,1)
in
y # [hd(x)]
end
Alternately, a cleaner way of doing this same thing, that also handles the possibility of an empty list:
fun cycle3 [] = []
| cycle3 (x::xs) = xs # [x]
I'm writing an interactive calculator in OCaml with some simple commands. Users should be able, among other things, to define their own simple functions (mathematical functions), for instance
let f(x) = x
let g(x) = 2*f(x)
Now, the functions should be handled like in functional languages, that means they should remember their time-of-creation environment. That means, that with a function I have to keep a closure of its environment, which is functions and variables.
I keep currently defined functions in a list of tuples formed like (functions_present_at_the_time_of_creation, variables_present_at_the_time_of_creation, function_name, function_argument_names, function_formula). When I try to add a new function to the list of functions (let's assume, that it's not currently defined and I don't have to overwrite anything), I recurrently iterate to the end of the list of functions and there would like to add a new tuple.
The problem is, assuming my current functions list is of type (a*b*c*d*e) list when i try to add a tuple with itself to the end of it, it changes its type to ((a*b*c*d*e) list*f*g*h*i) list. What can I do to be able to perform such addition of a list to itself, encapsulated in a tuple?
Here's some simple SSCCE I wrote while trying to find a workaround to this issue.
let rec add_to_end list list_copy dummy = match list with
| [] -> [(list_copy, dummy)]
| h::t -> h::(add_to_end t list_copy dummy)
let add list dummy = add_to_end list list dummy
This one tries to do it with a copy of the list. The following one is written without using of a copy (both of these examples don't work, of course):
let rec add_to_end list dummy = match list with
| [] -> [(list, dummy)]
| h::t -> h::(add_to_end t dummy)
The first example doesn't work when trying to use the function add, but when doing it for instance this way (in the interpreter):
let l = [];;
let l = add_to_end l l 1;;
let l = add_to_end l l 2;;
let l = add_to_end l l 3;;
Then it works fine. I'd appreciate any help, I may think about changing the design also, any proposals are very welcome.
Edit: Here's the output of the above commands:
# let l = [];;
val l : 'a list = []
# let l = add_to_end l l 1;;
val l : ('a list * int) list = [([], 1)]
# let l = add_to_end l l 2;;
val l : (('a list * int) list * int) list = [([], 1); ([([], 1)], 2)]
# let l = add_to_end l l 3;;
val l : ((('a list * int) list * int) list * int) list =
[([], 1); ([([], 1)], 2); ([([], 1); ([([], 1)], 2)], 3)]
It's hard to tell whether you're aware that OCaml lists are immutable. You can't add a value to the end of an existing list. An existing list can never be changed. You can create a new list with a value added to the end. If you do this, I don't see why you would want to add a pair to the end consisting of the list and the new value. I suspect you're thinking about it wrong. Here's a function that takes a list and an integer and adds the integer to the end of the list.
# let rec addi i list =
match list with
| [] -> [i]
| h :: t -> h :: addi i t
;;
val addi : 'a -> 'a list -> 'a list = <fun>
# let x = [1;2;3];;
val x : int list = [1; 2; 3]
# addi 4 x;;
- : int list = [1; 2; 3; 4]
# x;;
- : int list = [1; 2; 3]
#
The function returns a new list with the value added to the end. The original list isn't changed.
As a side comment, it's much more idiomatic to add values to the front of a list. Repeatedly adding to the end of the list is slow--it gives quadratic behavior. If you want the other order, the usual thing to do is add everything to the front and then reverse the list--this is still linear.
Edit
Apparently you really want a function that looks something like this:
let f a list = list # [(list, a)]
This is not realistically possible, the types don't work out right. A list can contain things of only one type. So you can conclude that the type of the list t is the same as the type (t, v) list, where v is the type of a. This is a recursive type, not something you would really want to be working with (IMHO).
You can actually get this type in OCaml using -rectypes:
$ ocaml -rectypes
OCaml version 4.00.0
# let f a list = list # [(list, a)];;
val f : 'a -> (('b * 'a as 'c) list as 'b) -> 'c list = <fun>
#
But (as I say) it's something I would avoid.
Edit 2
Now that I look at it, your first code sample avoids requiring a recursive type because you
specify two different copies of the list. Until you call the function with the same list, these are potentially different types. So the function type is not recursive. When you call with two copies of the same list, you create a new value with a type that's different than the type of the list. It only works because you're using the same name l for different values (with different types). It won't work in a real program, where you'd need a single type representing your list.
As another side comment: the beauty of adding values to the beginning of a list is that the old value of the list is still there. It's the tail of the new list. This seems lot closer to what you might actually want to do.