I want to pass two arguments from command line. I know how to pass one argument using CommandLine.arguments .
val arg1 = CommandLine.arguments();
But how to pass two arguments and use it?
Thank you.
As John says, since CommandLine.arguments : unit -> string list, you can extract both the first and the second argument by regular pattern matching on this list. Assuming the two first arguments can be named foo and bar, and should both be interpreted as strings, and that any other number of arguments (0, 1, 3, ...) is an error, you could write:
fun main () =
let val (foo, bar) = case CommandLine.arguments () of
[foo, bar] => (foo, bar)
| _ => raise Fail "Usage: tool <foo> <bar>"
in ...
end
And performing transformations on foo and bar, such as conversion to numbers, is not terribly difficult from here. But in case your command-line arguments are optional, or you do not wish for the order of them to matter, or you want to provide multiple ways of specifying them – e.g. -h being an alias for --human-readable while both work – you should consider using a utility library in SML/NJ called GetOpt.
It provides a framework for specifying how command-line arguments should be interpreted in a dynamic way. You can read the SML/NJ GetOpt documentation, which provides a small example. It is a quite generic library and adds some complexity that is perhaps not warranted until you have quite many arguments and cannot be bothered to handle all legal combinations of them.
The type of CommandLine.arguments is
unit -> string list
It doesn't return a single string, it returns a list of strings. Any passed argument will be in the list. You just have to extract them.
If you are passing a single string which splits into multiple arguments with something other than a space as a delimiter you could use String.tokens on it. For example,
String.tokens (fn c => c = #"|") "abc|de|fgh";
Which yields ["abc","de","fgh"]. You need to pass to String.tokens a Boolean-valued function which can tell when a character is a delimiter.
I figured it out:
Just use
sml "file.sml" "arg1" "arg2"
where arg1 and arg2 are stored in a list and can be extracted in program using "tl" and "hd" function of list.
Related
I am using a 3rd party module which exposes a function:
val pp : Format.formatter -> 'a -> unit
Unfortunately it doesn't expose a to_string (or show) function.
I want to find a way to use the result of pp in a format string, something like:
let output = Format.sprintf "Result: %s" (SomeModule.pp fmt myval)
But pp writes to fmt and returns unit so of course this is not valid.
I can tell I need to somehow make a formatter to pass to pp that writes to a string buffer, that I can then get contents of as a string, which I can then pass as an arg to sprintf
The use of pp like functions for making types printable seems pretty ubiquitous in OCaml (e.g. ppx_deriving show generates them) so I feel like there should be a simple way to achieve this, but I'm currently missing it.
By using asprintf instead, it's possible to use the %a format specifier to pass two arguments, a printer function and the value to be printed, which will then be formatted accordingly and inserted in its place:
let output = Format.asprintf "Result: %a" SomeModule.pp myval
The reason asprintf has to be used instead of sprintf is that the latter specifies an "input source" (the second argument of the format type) of type unit, while the former uses a formatter. This is what's going to be passed to the printer.
It still alludes me why there's a need for sprintf though, rather than just having asprintf. Perhaps there's some performance-related reason for it, but my guess is that it's just an artifact of history.
I just started learning Erlang so please bear with me if this question seems a little simple.
Hi guys. I've been thinking about it for a while but nothing I come up with seems to be working.
I am writing an Erlang function that is supposed to take a list as an argument then print the list with my name in front of it. For the purposes of this question, let's say my name is "James".
If I type in testmodule:NameInFront("Legible", "Hey", "Think").
Erlang should return ["James", "Legible", "Hey", "Think"]
This is the code I have so far:
-module(testmodule).
-export([NameInFront/1]).
NameInFront(List)-> ["James"]++[List].
It works just fine when I type in just one word, which I guess it the fault of the NameInFront/1 part but I want it to be able to handle any amount of words I type in. Anyone know how I can get my function to handle multiple inputs? Thank you very much.
I'm not quite sure what you mean: whether you want your function to be variadic (take a flexible number of arguments), or you are having trouble getting your lists to join together properly.
Variadic functions are not the way Erlang works. FunctionName/Arity defines the concrete identity of a function in Erlang (discussed here). So our way of having a function take multiple arguments is to make one (or more) of the arguments a list:
print_terms(Terms) -> io:format("~tp~n", [Terms]).
The io:format/2 function itself actually takes a list as its second function, which is how it deals with a variable number of arguments:
print_two_things(ThingOne, ThingTwo) ->
io:format("~tp~n~tp~n", [ThingOne, ThingTwo]).
In your case you want to accept a list of things, add your name to it, and print it out. This is one way to do it.
name_in_front(ListOfStrings) ->
NewList = ["James" | ListOfStrings],
io:format("~p~n", [NewList]).
Using the ++ operator is another (which is actually a different syntax for a recursive operation which expands to the exact same thing, ):
name_in_front(ListOfStrings) ->
NewList = ["James"] ++ ListOfStrings,
io:format("~tp~n", [NewList]).
But that's a little silly, because it is intended to join two strings together in a simple way, and in this case it makes the syntax look weird.
Yet another way would be to more simply write a function that take two arguments and accomplishes the same thing:
any_name_in_front(Name, ListOfThings) ->
io:format("~tp~n", [[Name | ListOfThings]]).
The double [[]] is because io:format/2 takes a list as its second argument, and you want to pass a list of one thing (itself a list) into a single format substitution slot (the "~tp" part).
One thing to note is that capitalization matters in Erlang. It has a meaning. Module and function names are atoms, which are not the same thing as variables. For this reason they must be lowercase, and because they must be lowercase to start with the convention is to use underscores between words instead of usingCamelCase. Because, well, erlangIsNotCpp.
Play around in the shell a bit with the simple elements of the function you want, and once you have them ironed out write it into a source file and give it a try.
I want to parse the argument list of a Lua function call in C++ using Qt (4.8) in order to avoid a dependency to the Lua interpreter. The comma-separated argument list can be assumed to consist only of string literals and numbers. Eventually the result should be available as a QStringList. The tricky part there is to cope with commas that are part of string arguments as well with the fact that string arguments may use single or double quotes. Until I get to a solution (using regular expressions) myself, somebody might already have dealt with that or a similar problem.
Example:
The argument list string
"Foo", "not 'bar'", 'a, b ,c', 42, 1e-8
should be transformed to a string list containing the items
Foo, not 'bar', a, b, c, 42 and 1e-8
(omitting the quotes per item to avoid confusion)
Not familiar with all the possibilities of your arguments, but the examples you mentioned get correctly matched with this: (?<=")[\w',-]*?(?=")|(?<=^'|\s').*(?='(?:,|$))|[\w-]+, as seen here: https://regex101.com/r/rX7fX7/3
The idea is that you write the "difficult" situations in alternations, preferably to the left, while the less difficult solutions to the right. This way, the engine will first check if a problem situation is present before trying to match whole words.
The current regex doesn't work correctly if quotes/doublequotes appear in middle of the arguments, but your examples didn't have such situations.
I have a function, I need to pattern match on another function to get two values. One need to be used in one function the other needs to be returned as output.
let myf A=
match (Functio A) with
|(frr,adll) -> funct frr 45
I need to execute the function funct and return adll as the output of the function myf. How can I do that?
Taking what you say at face value, the following code will do what you want I think:
let myf a =
let (frr, adll) = functio a in
funct frr 45;
adll
You may still have typing problems depending on what funct returns.
Note that you can replace a match that has only one alternative with just a let.
Also note that names beginning with an upper case letter are reserved for certain specific uses (such as value constructors). So you can't have a function named Functio or a parameter named A.
I want to have user-defined type in Ocaml which represents strings which starts with English letter and afterwards can have letters or digits. Is it possible to define such custom type?
Jeffrey Scofield is right: there is no way in OCaml to define a type that would be the subset of strings verifying a given condition. You might however simulate that to some extent with a module and abstract or private data type, as in:
module Ident : sig
type t = private string
val create: string -> t
val (^): t -> t -> t
(* declare, and define below other functions as needed *)
end = struct
type t = string
let create s = (* do some check *) s
let (^) s1 s2 = create (s1 ^ s2)
end;;
Of course, the create function should check that the first char of s is a letter and the other ones letters or digits and raise an exception if this is not the case, but this is left a an exercise. This way, you know that any s of type Ident.t respects the conditions checked in create: by making the type synonym private in the signature, you ensure that you must go through one of the functions of Ident to create such value. Conversely (s:>string) is recognized as a string, hence you can still use all built-in functions over it (but you'll get back string, not Ident.t).
Note however that there is particular issue with string: they are mutable (although that is bound to change in the upcoming 4.02 version), so that you can alter an element of Ident.t afterwards:
let foo = "x0";;
let bar = Ident.create foo;;
foo.[0] <- '5';;
bar;;
will produce
- : Ident.t = "50"
If you restrict yourself to never modify a string in place (again this will be the default in the next OCaml's version), this cannot happen.
It's a little hard to answer, but I think the most straightforward answer is no. You want the type to be constrained by values, and this isn't something that's possible in OCaml. You need a language with dependent types for that.
You can define an OCaml type that represents such strings, but its values wouldn't also be strings. You couldn't use strings like "a15" as values of the type, or use the built-in ^ operator on them, etc. A value might look like S(Aa, [B1; B5]) (say). This is far too cumbersome to be useful.