How to convert a string to integer list in ocaml? - functional-programming

I need to pass two list as command line arguments in ocaml.
I used the following code to access it in the program.
let list1=Sys.argv.(1);;
let list2=Sys.argv.(2);;
I need to have the list1 and list2 as list of integers.
I am getting the error
This expression has type string but an expression was expected of type
int list
while processing.
How can I convert that arguments to a list of integers.
The arguments are passed in this format [1;2;3;4] [1;5;6;7]

Sys.argv.(n) will always be a string. You need to parse the string into a list of integers. You could try something like this:
$ ocaml
OCaml version 4.01.0
# #load "str.cma";;
# List.map int_of_string (Str.split (Str.regexp "[^0-9]+") "[1;5;6;7]");;
- : int list = [1; 5; 6; 7]
Of course this doesn't check the input for correct form. It just pulls out sequences of digits by brute force. To do better you need to do some real lexical analysis and simple parsing.
(Maybe this is obvious, but you could also test your function in the toplevel (the OCaml read-eval-print loop). The toplevel will handle the work of making a list from what you type in.)

As Sys.argv is a string array, you need to write your own transcription function.
I guess the simplest way to do this is to use the Genlex module provided by the standard library.
let lexer = Genlex.make_lexer ["["; ";"; "]"; ]
let list_of_string s =
let open Genlex in
let open Stream in
let stream = lexer (of_string s) in
let fail () = failwith "Malformed string" in
let rec aux acc =
match next stream with
| Int i ->
( match next stream with
| Kwd ";" -> aux (i::acc)
| Kwd "]" -> i::acc
| _ -> fail () )
| Kwd "]" -> acc
| _ -> fail ()
in
try
match next stream with
| Kwd "[" -> List.rev (aux [])
| _ -> fail ()
with Stream.Failure -> fail ()
let list1 = list_of_string Sys.argv.(1)
let list2 = list_of_string Sys.argv.(2)
Depending on the OCaml flavor you want to use, some other library may look more interesting. If you like yacc, Menhir may solve your problem in a few lines of code.

Related

F# define search function

I am new to F# and am having trouble with my code. Its a simple problem to define a function, search, with that take a boolean function and a list and return an index. So for example:
> search (fun x -> x > 10) [ 2; 12; 3; 23; 62; 8; 2 ];;
val it : int = 1
> search (fun s -> s < "horse") [ "pig"; "lion"; "horse"; "cow"; "turkey" ];;
val it : int = 3
What I have as of right now finds the right match but what I cant figure out is how to return a number instead of the rest of the list. I know I'm getting the list instead of a value back because I wrote "if f head then list". What I don't know is what I should put there instead or if what I have is not going to get the result I want.
Below is the code I have written.
let rec search f list =
match list with
| [] -> [-1]
| head::tail ->
if f head then list
else search f tail
Returning a number is easy, you just... return it. Your problem is that you don't have a number to return, because you can't derive it directly from the current state. You have to keep track of the number yourself, using some internal state variable.
When using recursion you change state by calling your function recursively with "modified" arguments. You're already doing that with the list here. To keep internal state in a recursive function you have to introduce another argument, but not expose it outside. You can solve that by using an internal recursive helper function. Here's one that keeps track of the previous item and returns that when it encounters a match:
let search f list =
let rec loop list prev =
match list with
| [] -> None
| head::tail ->
if f head then prev
else loop tail (Some head)
in
loop list None
That's a silly example, but I don't want to just solve your homework for you, because then you wouldn't learn anything. Using this you should be able to figure out how to keep a counter of which position the current item is in, and return that when it matches. Good luck!
You typically define an inner recursive function to help you carry state as you loop, and then call the inner function with an initial state.
let search predicate list =
let rec loop list index =
match list with
| [] -> -1
| head::tail ->
if predicate head then index
else loop tail (index + 1)
loop list 0

Simple example of recursive run through string characters in Erlang

I can't get how I can go through all characters in a string, can you please share a simple example?
I have a string, like
"function(){var a = 10; var b = 5; return a + b;}".
Now I want to "cycle" through the string character by character and do something depending on its value.
Here is my code which doesn't work, while running as lexme("some string here").:
lexme(S) ->
lexme(S, 1).
lexme([H | T], _) ->
io:fwrite("~p~n", [H]),
T.
In order to make lexme/2 recursive, it must call itself.
Try this:
lexme([H | T], _) ->
io:fwrite("~p~n", [H]),
lexme(T, 1).
I'm not sure what you intend to do with the second parameter. You're ignoring it, so why is it there?
You'll also want a function head that deals with the empty list so that the recursion can terminate, so the full definition would be something like this:
lexme([], _) ->
done;
lexme([H | T], _) ->
io:fwrite("~p~n", [H]),
lexme(T, 1).
See http://learnyousomeerlang.com/recursion for more information.

OCaml main function

I need a main function to run the others functions.
I tried this:
let main () =
let deck = make_mazo in
let jugadores = players [] 0 in
dothemagic deck jugadores 0 [] [] [];;
But I got this error:
File "game.ml", line 329, characters 37-39:
Error: Syntax error
I think ;; is the problem and I need a different way to end the code. Also try with only ; and the problem is the same.
[EDIT]
An update here
let main =
let deck = make_mazo [] in
let game = players deck [] 0 in
let dd = fst game in
let jugadores = snd game in
dothemagic dd jugadores 0 [] [] [] [];
let () = main;;
Error persist:
File "game.ml", line 253, characters 13-15:
Error: Syntax error
The other functions are working perfectly fine, but i need a main function because I want to run the program with ocaml game.ml or ocamlbuild game.native
[SECOND EDIT]
After #camlspotter response: The use of ; of your code is wrong. Remove it.
Update 2.0
let main =
let deck = make_mazo [] in
let game = players deck [] 0 in
let dd = fst game in
let jugadores = snd game in
dothemagic dd jugadores 0 [] [] [] []
let () = main;;
New Error:
File "game.ml", line 253, characters 0-3: Error: Syntax error
Think let is the problem now, so i try with this
let main =
let deck = make_mazo [] in
let game = players deck [] 0 in
let dd = fst game in
let jugadores = snd game in
dothemagic dd jugadores 0 [] [] [] []
main;;
But Error is:
File "game.ml", line 253, characters 4-6:
Error: Syntax error
There's nothing syntactically wrong with the code you show here.
Most likely the problem is near the end of the part you don't show, like around line 324 of the file.
If I had to guess, I'd say that line 324 ends with in :-)
As a side comment, you'll also need to call this main function. You might want the last line of the file to be something like this:
let () = main ()
(This line appears in many of my OCaml projects.)
In ocaml, there is no main function unlike other languages, see the code below :
let () = print_string "hello\n";;
let f = print_string "hello, this is f\n";;
let () = f;;
OCaml programs, unlike programs in many other languages, do not have a specific entry-point: all the code in a module (file) is evaluated in order from top to bottom, sort of like in a scripting language. A common idiom you'll see is:
let name = "World" (* I could have added a ;; at the
* end of this line, but that would
* have been unnecessary *)
let () =
Printf.printf "Hello, %s!\n" name
which will output
Hello, World!
The let () = ... may seem a bit wonky, but it's really just pattern-matching: the return type of Printf.printf is unit, () is also of type unit, the you're really just saying "match this unit value with the result of evaluating this expression". Basically, this idiom means "run this unit-type expression in a safe way".
A similar, although highly discouraged, idiom, uses the catch-all pattern:
let greet s =
match s with
| "" -> false
| _ ->
Printf.printf "Hello, %s!\n" s;
true
let name = "World"
let _ =
greet world
The catch-all pattern doesn't care about the type (or value) of the expression it's being matched against, and this idiom means "run this expression and discard whatever it returned".
To solve my problem, I had to write the functions in the following way,
let fun x =
let y = blabla in
code_returning_unit; (* Use ; for unit returns *)
return_value;; (* Use ;; for end of fun *)
Thanks all for the help.

F#: Using object expression with discriminated union

I have a recursive function that contains a series of matches that either make the recursive call back to the function, or make a call to failwith.
This is basically a hybrid implementation of the recursive descent parser descibed in Don Syme's Expert F# book (page 180) and the parsing example shown here: http://fsharpforfunandprofit.com/posts/pattern-matching-command-line/
Here is a snippet of my own code.
let rec parseTokenListRec tokenList optionsSoFar =
match tokenList with
| [] -> optionsSoFar
| SOURCE::t ->
match t with
| VALUE x::tt -> parseTokenListRec (returnNonValueTail t) {optionsSoFar with Source = (returnConcatHeadValues t)}
| _ -> failwith "Expected a value after the source argument."
| REGISTRY::t ->
...
A full code listing can be found at http://fssnip.net/nU
The way the code is currently written, when the function has finished working its way through the tokenList, it will return the optionsSoFar record that has been compiled via the object expression {optionsSoFar with Source = (returnConcatHeadValues t)}, or it will throw an exception if an invalid argument is found.
I want to refactor this so that the function does not rely on an exception, but will always return a value of some sort that can be handled by the calling function. The idea I have is to return a discriminated union rather than a record.
This discriminated union would be something like
type Result =
|Success of Options
|Failure of string
The problem I had when I tried to refactor the code was that I couldn't figure out how to get the success value of the DU to initialize via an object expression. Is this possible?
The examples I've looked at on MSDN (http://msdn.microsoft.com/en-us/library/vstudio/dd233237(v=vs.100).aspx), fsharpforfunandprofit (http://fsharpforfunandprofit.com/posts/discriminated-unions/) and elsewhere haven't quite cleared this up for me.
I'm worried that I'm not making any sense here. I'm happy to clarify if needed.
If I understand it correctly, in you current solution, the type of optionsSoFar is Options. The code becomes trickier if you change the type of optionsSoFar to your newly defined Result.
However, I think you do not need to do that - you can keep optionsSoFar : Options and change the function to return Result. This works because you never need to call the function recursively after it fails:
let rec parseTokenListRec tokenList optionsSoFar =
match tokenList with
| [] -> Success optionsSoFar
| SOURCE::t ->
match t with
| VALUE x::tt ->
{optionsSoFar with Source = (returnConcatHeadValues t)}
|> parseTokenListRec (returnNonValueTail t)
| _ -> Failure "Expected a value after the source argument."
| REGISTRY::t -> ...
If you actually wanted to update Source in a Result value, then I'd probably write something like:
module Result =
let map f = function
| Success opt -> f opt
| Failure msg -> Failure msg
Then you could write a transformation as follows:
resultSoFar
|> Result.map (fun opts -> {opts with Source = returnConcatHeadValues t})
|> parseTokenListRec (returnNonValueTail t)

Writing cat in OCaml: use of Unix.read

I'm trying to write small utilities to get used to Unix programming with OCaml. Here's my try for cat:
open Unix ;;
let buffer_size = 10
let buffer = String.create buffer_size
let rec cat = function
| [] -> ()
| x :: xs ->
let descr = openfile x [O_RDONLY] 0 in
let rec loop () =
match read descr buffer 0 buffer_size with
| 0 -> ()
| _ -> print_string buffer; loop () in
loop ();
print_newline ();
close descr;
cat xs ;;
handle_unix_error cat (List.tl (Array.to_list Sys.argv))
It seems that the problem is that, on the last call to read, the buffer doesn't entirely fill since there's nothing more to read, the end of what the buffer previously contained gets printed too. I read a few example codes using read and they didn't seem to use String.create every time they refill the buffer (which, anyway, still fills it with some characters...) ; so what should I do? Thanks.
The return of Unix.read (which you ignore, except checking for 0) is the number of characters that you've read, so you only should use that many characters of the buffer.
But really, why bother using the low-level Unix stuff? Why not use the regular OCaml file opening and reading functions?

Resources