I have to get two integers, separated by a space, in two different variables, in just one input.
I've done let (c, d) = Scanf.scanf " %d %d" (fun a b -> (a, b)) but I get this error : This expression has type 'a * 'b but an expression was expected of type 'c -> 'd -> 'e
How can I do it?
Thanks!
Your code works and does not raise any error
let (c, d) = Scanf.scanf " %d %d" (fun a b -> (a, b))
Since this code reads from stdin, you might have written
let (c, d) = Scanf.scanf " %d %d" (fun a b -> (a, b))
1 2;;
in a toplevel which will result in the error that you are seeing: the parser reads the extract above as
Scanf.scanf " %d %d" (fun a b -> (a, b)) 1 2
and complains that Scanf.scanf " %d %d" (fun a b -> (a, b)) is a tuple that cannot be applied to 1 and 2.
Related
I have experience with functional programming in general, but I'm new to F#, and I can't get this code to compile no matter what I try:
let group2<'T> (sq: seq<'T>) : seq<'T * 'T> =
Seq.fold (fun (p, l) b -> match p with
| None -> (Some b, l)
| Some v -> (None, (v, b) :: l)) (None, []) sq
I don't understand what this error message is trying to tell me, and I can't for the life of me figure out why it won't compile as-is;
main.fs(2,19): error FS0001: This expression was expected to have type
'seq<'T * 'T>'
but here has type
''a * 'b'
main.fs(4,65): error FS0001: This expression was expected to have type
'seq<'T * 'T>'
but here has type
''a * 'b'
anyone with more F# experience have some advice?
So if you update your code like this
let group2<'T> (sq: seq<'T>) : seq<'T * 'T> =
Seq.fold (fun (p ,l) b -> match p with
| None -> (Some b, l)
| Some v -> (None, (v, b) :: l)) (None, []) sq
|> snd
|> List.rev
|> Seq.ofList
It can work (by removing the state, and converting back from list to sequence). For example
group2 [1;2;3;4]
yields
[(1, 2); (3, 4)]
It's not very idiomatic as it mixes sequences and lists.
A more idiomatic code only for (even) lists:
let rec group2 (xs:'T list) =
match xs with
| [] -> []
| x::y::xs -> ( x, y)::group2 xs
| _ -> failwith "not even"
Basically you deal with 3 choices,
The list is empty, there are no pairs you return an empty list.
There are two items at the start, you pair them in a tuple and process the rest of the list recursively
There's only one item left, we fail because it's not posible to create a tuple with nothing*
If you want to consider odd lists, you can use option types: e.g. None/Some
let rec group2 (xs:'T list) =
match xs with
| [] -> []
| [x] -> [Some x, None]
| x::y::xs -> (Some x,Some y)::group2 xs
Finally you could use the chunkBySize library function for either (even) lists or sequences:
[1;2;3;4]
|> Seq.chunkBySize 2
|> Seq.map (fun a -> a.[0], a.[1])
or
[1;2;3;4]
|> List.chunkBySize 2
|> List.map (fun a -> a.[0], a.[1])
I'm a beginner in OCaml and algorithms.
I'm trying to get the number of 5 digits numbers with no repeating digits bigger than 12345.
Here is what I did in OCaml, I tried to make as tail recursive as possible, and I also used streams. But still, due to size, it stack overflowed:
type 'a stream = Eos | StrCons of 'a * (unit -> 'a stream)
let rec numberfrom n= StrCons (n, fun ()-> numberfrom (n+1))
let nats = numberfrom 1
let rec listify st n f=
match st with
|Eos ->f []
|StrCons (m, a) ->if n=1 then f [m] else listify (a ()) (n-1) (fun y -> f (m::y))
let rec filter (test: 'a-> bool) (s: 'a stream) : 'a stream=
match s with
|Eos -> Eos
|StrCons(q,w) -> if test q then StrCons(q, fun ()->filter test (w ()))
else filter test (w ())
let rec check_dup l=
match l with
| [] -> false
| h::t->
let x = (List.filter (fun x -> x = h) t) in
if (x == []) then
check_dup t
else
true;;
let digits2 d =
let rec dig acc d =
if d < 10 then d::acc
else dig ((d mod 10)::acc) (d/10) in
dig [] d
let size a=
let rec helper n aa=
match aa with
|Eos-> n
|StrCons (q,w) -> helper (n+1) (w())
in helper 0 a
let result1 = filter (fun x -> x<99999 && x>=12345 && (not (check_dup (digits2 x)))) nats
(* unterminating : size result1 *)
(*StackOverflow: listify result1 10000 (fun x->x) *)
I can't reproduce your reported problem. When I load up your code I see this:
# List.length (listify result1 10000 (fun x -> x));;
- : int = 10000
# List.length (listify result1 26831 (fun x -> x));;
- : int = 26831
It's possible your system is more resource constrained than mine.
Let me just say that the usual way to code a tail recursive function is to build the list up in reverse, then reverse it at the end. That might look something like this:
let listify2 st n =
let rec ilist accum st k =
match st with
| Eos -> List.rev accum
| StrCons (m, a) ->
if k = 1 then List.rev (m :: accum)
else ilist (m :: accum) (a ()) (k - 1)
in
if n = 0 then []
else ilist [] st n
You still have the problem that listify doesn't terminate if you ask for more elements than there are in the stream. It might be better to introduce a method to detect the end of the stream and return Eos at that point. For example, the filter function might accept a function that returns three possible values (the element should be filtered out, the element should not be filtered out, the stream should end).
The problem is that the size of your stream result1 is undefined.
Indeed, nats is an never-ending stream: it never returns Eos.
However, filtering a never-ending stream results in another never-ending stream
since a filtered stream only returns Eos after the underlying stream does so:
let rec filter (test: 'a-> bool) (s: 'a stream) : 'a stream=
match s with
| Eos -> Eos
| StrCons(q,w) -> if test q then StrCons(q, fun ()->filter test (w ()))
else filter test (w ())
Consequently, size result1 is stuck trying to reach the end of integers.
Note also that, in recent version of the standard library, your type stream is called Seq.node.
I would like to log (print for now) all the elements in results before reducing it for return. Is there a way to achieve that?
let calculate ~size_of_experiment:s ~number_of_buckets:n =
let results = run_experiments s n in
List.iter (fun x -> print_endline x) results;
List.fold_left (fun x y -> x + (snd y)) 0 results
The code above does not compile:
Error: This expression has type (int * int) list
but an expression was expected of type string list
Type int * int is not compatible with type string
Your only problem seems to be that elements of the list are of type (int * int) and you are treating them as strings.
let string_of_int_pair (a, b) = Printf.sprintf "(%d, %d)" a b
let calculate ~size_of_experiment:s ~number_of_buckets:n =
let results = run_experiments s n in
List.iter (fun x -> print_endline (string_of_int_pair x)) results;
List.fold_left (fun x y -> x + (snd y)) 0 results
The more general problem is that it would be really nice to have a way to print values of various types without writing the code yourself for each case. For that you can use something like deriving.
The following code runs with no errors:
let f x y =
print_int (max x y);
print_char ' ';
print_int (x + y) in
for i = 1 to Scanf.scanf "%d" (fun x -> x) do
Scanf.scanf "\n%d %d" f;
print_newline ();
done;
But when I declare a variable fmt to hold the format "\n%d %d" and pass it to scanf,I get an error,here is the new code:
let f x y =
print_int (max x y);
print_char ' ';
print_int (x + y) in
let fmt = "\n%d %d" in (* added *)
for i = 1 to Scanf.scanf "%d" (fun x -> x) do
Scanf.scanf fmt f; (* edited *)
print_newline ();
done;
I get this error:
File "prog.ml", line 7, characters 16-19:
Error: This expression has type string but an expression was expected of type
('a, Scanf.Scanning.in_channel, 'b, 'c -> 'd, 'a -> 'e, 'e) format6
Why does it work differently?is there any difference between the two codes?
The handling of printf/scanf formats in OCaml uses some compiler magic that treats a string constant as a format in the proper context. The problem is that you no longer have a string constant.
You can pre-convert a string constant to a format using the format_of_string function.
Change your let fmt = line to this:
let fmt = format_of_string "\n%d %d" in
This makes your code work for me.
As strange as it may seem, this is actually a value-added feature: scanning functions are type-checked at compile time, and in order to do this the compiler has to be able to clearly see the format string at the call site and make sure that no shenanigans are going on with it. Such shenanigans could lead to undesirable behaviour, as in the following example:
let fmt = "%d" in
let fmt' = fmt ^ (if input_type = "int" then " %d" else " %f") in
(* input_type is defined somewhere else in the program *)
(* the format string could now be either "%d %d" or "%d %f" *)
let a,b = Scanf.scanf fmt' (fun a b -> a,b)
(* the compiler cannot infer a type for `b` *)
I want to do something as simple as this:
Print a list.
let a = [1;2;3;4;5]
How can I print this list to Standard Output?
You should become familiar with the List.iter and List.map functions. They are essential for programming in OCaml. If you also get comfortable with the Printf module, you can then write:
open Printf
let a = [1;2;3;4;5]
let () = List.iter (printf "%d ") a
I open Printf in most of my code because I use the functions in it so often. Without that you would have to write Printf.printf in the last line. Also, if you're working in the toploop, don't forget to end the above statements with double semi-colons.
You can do this with a simple recursion :
let rec print_list = function
[] -> ()
| e::l -> print_int e ; print_string " " ; print_list l
The head of the list is printed, then you do a recursive call on the tail of the list.
print_string (String.concat " " (List.map string_of_int list))
If the question is about finding the quickiest way to implement this, for example when debugging, then we could say that:
extended standard libraries (e.g. batteries) typically have some additional functions:
List.print
~first:"[" ~sep:";" ~last:"]" (fun c x -> Printf.fprintf c "%d" x) stdout a
this tiny syntax extension that I wrote some time ago allows you to write:
<:print<[$!i <- a${$d:i$}{;}]>>
automatic generation is not immediately available (because of the lack of run-time type information in OCaml data representation) but can be achieved using either code generation from the types, or run-time types.
I'm very late answering, but here's another way:
let print_list f lst =
let rec print_elements = function
| [] -> ()
| h::t -> f h; print_string ";"; print_elements t
in
print_string "[";
print_elements lst;
print_string "]";;
To print an int list, we could write:
print_list print_int [3;6;78;5;2;34;7];;
However if we were going to do this a lot, it would save time to specialize the function using partial application:
let print_int_list = print_list print_int;;
Which we can now use like so:
print_int_list [3;6;78;5;2;34;7];;
What if we wanted to do something pretty complex, like printing an int list list? With this function, it's easy:
(* Option 1 *)
print_list (print_list print_int) [[3;6;78];[];[5];[2;34;7]];;
(* Option 2 *)
let print_int_list_list = print_list (print_list print_int);;
print_int_list_list [[3;6;78];[];[5];[2;34;7]];;
(* Option 3 *)
let print_int_list_list = print_list print_int_list;;
print_int_list_list [[3;6;78];[];[5];[2;34;7]];;
Printing an (int * string) list (i.e. a list of pairs of ints and strings):
(* Option 1 *)
print_list (fun (a, b) -> print_string "("; print_int a; print_string ", "; print_string b; print_string ")") [(1, "one"); (2, "two"); (3, "three")];;
(* Option 2 *)
let print_pair f g (a, b) =
print_string "(";
f a;
print_string ", ";
g b;
print_string ")";;
print_list (print_pair print_int print_string) [(1, "one"); (2, "two"); (3, "three")];;
(* Option 3 *)
let print_pair f g (a, b) =
print_string "(";
f a;
print_string ", ";
g b;
print_string ")";;
let print_int_string_pair = print_pair print_int print_string;;
print_list print_int_string_pair [(1, "one"); (2, "two"); (3, "three")];;
(* Option 4 *)
let print_pair f g (a, b) =
print_string "(";
f a;
print_string ", ";
g b;
print_string ")";;
let print_int_string_pair = print_pair print_int print_string;;
let print_int_string_pair_list = print_list print_int_string_pair;;
print_int_string_pair_list [(1, "one"); (2, "two"); (3, "three")];;
I would do this in the following way:
let a = [1;2;3;4;5];;
List.iter print_int a;;
Actually, you can decouple printing a list and turning a list into a string. The main advantage for doing this is that you can use this method to show lists in logs, export them to CSVs...
I often use a listHelper module, with the following :
(** Generic method to print the elements of a list *)
let string_of_list input_list string_of_element sep =
let add a b = a^sep^(string_of_element b) in
match input_list with
| [] -> ""
| h::t -> List.fold_left add (string_of_element h) t
So, if I wanted to output a list of floats to a csv file, I could just use the following :
let float_list_to_csv_row input_list = string_of_list input_list string_of_float ","
Just a solution with %a :
open Printf
let print_l outx l =
List.map string_of_int l
|> String.concat ";"
|> fprintf outx "%s"
Test :
# printf "[%a]" print_l [1;2;3] ;;
[1;2;3]- : unit = ()
# printf "[%a]" print_l [];;
[]- : unit = ()
let print_list l =
let rec aux acc =
match acc with
| [] -> ()
| x :: tl ->
Printf.fprintf stdout "%i"; aux tl
in aux l
Or
let sprintf_list l =
let acc = ref "{" in
List.iteri (fun i x ->
acc := !acc ^
if i <> 0
then Printf.sprintf "; %i" x
else Printf.sprintf "%i" x
) l;
!acc ^ "}"
let print_list l =
let output = sprintf_list l in
Printf.fprintf stdout "%s\n" output