How do I go about passing command-line arguments to an SML script? I'm aware that there is a CommandLine.arguments() function of the right type (unit -> string list), but invoking the interpreter like so:
$ sml script_name.sml an_argument another_one
doesn't give me anything. Pointers?
Try this.
(* arg.sml *)
val args = CommandLine.arguments()
fun sum l = foldr op+ 0 (map (valOf o Int.fromString) l)
val _ = print ("size: " ^ Int.toString (length args) ^ "\n")
val _ = print ("sum: " ^ Int.toString (sum args) ^ "\n")
val _ = OS.Process.exit(OS.Process.success)
The exit is important, otherwise you get a bunch of warnings treating the arguments as extensions. That is, it tries to parse the remaining arguments as files, but since they don't have an sml extension, they are treated as compiler extensions.
$ sml arg.sml 1 2 3
Standard ML of New Jersey v110.74 [built: Thu Jan 10 18:06:35 2013]
[opening arg.sml]
[autoloading]
[library $SMLNJ-BASIS/basis.cm is stable]
[autoloading done]
size: 3
sum: 6
val args = ["1","2","3"] : string list
val sum = fn : string list -> int
In programs compiled with MLton, commandline args are straightforward:
$ mlton arg.sml
$ ./arg a b c
size: 3
sum: 6
In SML/NJ it's more of a hassle to create a standalone executable.
Related
So I need to write a function that will triple every number in a list of integers
Here is what I have so far:
let number = [1; 2; 3; 4];;
let rec print_list_int myList = match myList with
| [] -> print_endline "This is the end of the int list!"
| head::body ->
begin
print_int head * 3;
print_endline "";
print_list_int body *3
end
;;
print_list_int number;;
It doesn't seem to do anything useful, any ideas where I went wrong? Need it outputting but it also doesn't do that. Thanks in advance! :)
This expression:
print_int head * 3
is interpreted like this:
(print_int head) * 3
Because function calls (application) have high precedence. You need to parenthesize like this:
print_int (head * 3)
The similar case below is a different problem: (print_list_int body) * 3 doesn't make sense but print_list_int (body * 3) also doesn't make sense. You can't multiply a list by 3. However, you don't need to multiply at this call. The print_list_int function will (recursively) do the multiplying for you.
Update
If I make the changes I hinted at above, I see this in the OCaml toplevel:
val print_list_int : int list -> unit = <fun>
# print_list_int number;;
3
6
9
12
This is the end of the int list!
- : unit = ()
#
Note that the most elegant way to achieve what you're trying to do is to use List.iter. It applies a given function (returning unit) to each element of a List.
let print_triples = List.iter (fun x ->
print_endline (string_of_int (3*x))
);;
val print_triples : int list -> unit = <fun>
And here you go:
# print_triples [1;2;3;4;5];;
3
6
9
12
15
- : unit = ()
I have this simple function which drives me crazy:
it should be a function of this type :
myfunction : (int * int list) list -> int -> int
For each tuples of the first argument :
When the second argument matches the first element of the tuple then the function return the last element of the list in the tuple.
If no matches it should return -1.
let rec myfunction alist anum =
let last_e l =
let len = List.length l in
List.nth l (len - 1) in
match alist with
| [] -> -1
| (n , ln) :: q -> if n = anum then last_e ln
else myfunction q anum
But my function does not work and I have this error message in utop:
Error: This expression has type 'a option but an expression was expected of type int
I don't know where the "option" type comes from.
This can happen if you are using some OCaml toplevel (e.g. utop) and you have these lines in your .ocamlinit file
#require "core.top" ;;
open Core.Std ;;
This enables the Core libraries, where List.nth has type:
μ> List.nth;;
- : 'a list -> int -> 'a option = <fun>
instead of standard OCaml's List.nth : 'a list -> int -> 'a.
So, when you fire up your toplevel and say:
μ> #use "myfunction.ml";;
you get the same error you cited in the question.
By the way, if you'd like to keep using Core, there is a List.last function.
Taken from the chapter 18 of the Real World OCaml book, I'm trying to break down the example given.
My scope, to just make the GET call and print something of the JSON we get back.
This is my code ( it's supposed to be a subset of the example given )
(* libraries *)
open Core.Std
open Async.Std
(* Generate a DuckDuckGo search URI from a query string *)
let query_uri query =
let base_uri = Uri.of_string "http://api.duckduckgo.com/?format=json" in
Uri.add_query_param base_uri ("q", [query])
(* Extract the "Definition" or "Abstract" field from the DuckDuckGo results *)
let get_definition_from_json json_string =
match Yojson.Safe.from_string json_string with
| `Assoc kv_list ->
let find key =
begin match List.Assoc.find kv_list key with
| None | Some (`String "") -> None
| Some s -> Some (Yojson.Safe.to_string s)
end
in
begin match find "Abstract" with
| Some _ as x -> x
| None -> find "Definition"
end
| _ -> None
(* Execute the DuckDuckGo search *)
let get_definition word =
print_endline ("get_definition word:" ^ word);
Cohttp_async.Client.get (query_uri word)
>>= fun (_, body) ->
Pipe.to_list (Cohttp_async.Body.to_pipe body)
>>| fun strings ->
(word, get_definition_from_json (String.concat strings))
(* run *)
let () =
get_definition "OCaml"
>>= fun (word, def) ->
print_endline ("- word: " ^ word);
(
match def with
| None -> print_endline "[EMPTY]"
| Some str -> print_endline str
)
My issue is that I get this error when compiling:
ocaml setup.ml -build
Finished, 0 targets (0 cached) in 00:00:00.
+ /Users/antouank/.opam/system/bin/ocamlfind ocamlc -c -g -annot -bin-annot -thread -package yojson -package threads -package textwrap -package re2 -package core -package cohttp.async -I src -o src/main.cmo src/main.ml
File "src/main.ml", line 48, characters 18-41:
Error: This expression has type unit but an expression was expected of type
'a Async.Std.Deferred.t = 'a Async_kernel.Deferred0.t
Command exited with code 2.
Compilation unsuccessful after building 2 targets (0 cached) in 00:00:00.
E: Failure("Command ''/usr/local/bin/ocamlbuild' src/main.native -use-ocamlfind -tag debug' terminated with error code 10")
make: *** [build] Error 1
How can I get the string out of that Deferred, and what does that error mean exactly?
In the book, the example is run with a weird Command wrap, so I cannot see how to pull it out.
The problem in your definition of run is that the anonymous function
fun (word, def) ->
print_endline ("- word: " ^ word);
(
match def with
| None -> print_endline "[EMPTY]"
| Some str -> print_endline str
)
is not correctly typed to be used with a monadic operator >>=. It has type string * string -> unit while the >>= would here expect a function of type string * string -> unit Deferred.t.
If you look at the example of an echo server in the very same chapter, it will suggest the following approach:
let run () =
get_definition "OCaml"
>>= fun (word, def) ->
print_endline ("- word: " ^ word);
(
match def with
| None -> print_endline "[EMPTY]"
| Some str -> print_endline str
);
Deferred.return()
let () =
ignore(run ());
never_returns (Scheduler.go ())
I would write (for debugging) a printer for a list of ((string * string) * 'a)
I tried with:
(* print a list of ((string * string) * 'a) *)
let rec print_list = function
[] -> Printf.printf "\n empty list \n %!"; ()
| ((s1,s2),a)::l -> Printf.printf "\n(s1,s2)= %s %s \n %!" s1 s2; print_list l;;
but it doesn't print anything.
It should print at least empty list, right?
In many languages (C and Ocaml) you'll better put the \n at end of printf format control string, or force the stdout to be flushed. Output to stdout is usually buffered (for performance reasons).
You should read the documentation of Ocaml before coding in Ocaml.
You may also want to call (from Pervasives) print_newline; read carefully documentation of Printf module; you could end your printf format string with %!
Here is an example (copied from your edited question) with Ocaml 4.01:
% ocaml
OCaml version 4.01.0
# (* print a list of ((string * string) * 'a) *)
let rec print_list = function
[] -> Printf.printf "\n empty list \n %!"; ()
| ((s1,s2),a)::l -> Printf.printf "\n(s1,s2)= %s %s \n %!" s1 s2;
print_list l;;
val print_list : ((string * string) * 'a) list -> unit = <fun>
# print_list [];;
empty list
- : unit = ()
#
As you can see, empty list gets printed. In the above code, % is a shell prompt, # is an ocaml toplevel prompt. Your function is copied verbatim. print_list [];; is input at toplevel.
I already searched the Web, I have Real World Haskell but I can't figure how to print a list of lists of Integers when that list is returned by combinatoricsGeneration.combinations.
I found the module at http://www.polyomino.f2s.com/david/haskell/combinatorics.html The functions have no type signature, so Haskell has to infer everything. I even tried adding signatures but the error is still there (more specific one).
The source code I am using from that module is:
combinationsOf 0 _ = [[]]
combinationsOf _ [] = []
combinationsOf k (x:xs) = map (x:) (combinationsOf (k-1) xs)
++ combinationsOf k xs
combinations k n = combinationsOf k [1..n]
I added the following signatures to see if that made a difference but it did not:
combinationsOf :: Integer -> [a] -> [[a]]
combinations :: Integer -> Integer -> [[Integer]]
My Haskell source file is:
module Main
where
import IO
import qualified CombinatoricsGeneration as CG
main = putStr $ unlines $ map show CG.combinations(6, 8)
The compilation of CombinatoricsGeneration is ok. But the one of my source file produces an error:
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 6.12.3
$ ghc -c CombinatoricsGeneration.hs
$ ghc -o test CombinatoricsGeneration.o test.hs
test.hs:6:37:
Couldn't match expected type `[a]'
against inferred type `t -> t1 -> [[t1]]'
In the second argument of `map', namely `CG.combinations'
In the second argument of `($)', namely
`map show CG.combinations (6, 8)'
In the second argument of `($)', namely
`unlines $ map show CG.combinations (6, 8)'
However the following line works fine:
main = putStr $ unlines $ map show [[1,2],[2],[3]]
Could you help me to display that simple list ?
TIA
You are calling the function wrongly. (6, 8) is a tuple (Num a1, Num a2) => (a1, a2), so
CG.combinations(6, 8)
will actually require a signature of CG.combinations as
(Num a1, Num a2) => (a1, a2) -> b
instead of a1 -> a2 -> b.
There is also a problem in precedence because map show will apply on the function CG.combinations, instead of the result of CG.combinations (6, 8).
You should call the function as
putStr $ unlines $ map show (CG.combinations 6 8)
-- # ^^^^^^^^^^^^^^^^^^^^^