I am trying sum up inside a tuple using matching pattern. Here is what I have done
let rec sum = function
| [] -> (0,0,0,0)
| obj::rest -> let (cc, cd, cr, ca) = sum rest in
(obj#method1 + cc, obj#method2 + cd
obj#method3 + cr, obj#method4 + ca) in
This recursive function can take a list of objects and return a tuple like (12893, 82382, 182942, 348934)
I got the error This 'object' might be unmatched. What is a good workaround for that issue?
UPDATE
method the_method (pays:string) =
let obj_list = self#return_data_country
let rec sum = function
| [] -> (0,0,0,0)
| obj::rest -> let (cc, cd, cr, ca) = sum rest in
(obj#method1 + cc, obj#method2 + cd
obj#method3 + cr, obj#method4 + ca) in
let sum_cc, sum_cd, sum_cr, sum_ca = sum obj_list in
let basic_info = (nth obj_list 0) in
("\nCountry : " ^ basic_info#method5 ^ "\n" ^
"UPDATE: " ^ basic_info#method6 ^ "\n" ^
"CC: " ^ string_of_int sum_cc ^ "\n" ^
"CD: " ^ string_of_int sum_cd ^ "\n" ^
"CR: " ^ string_of_int sum_cr ^ "\n" ^
"CA: " ^ string_of_int sum_ca ^ "\n" ^)
This error message is talking about the literal token object. You have an object with no matching end. As #Yawar says, the error isn't in the lines you show here.
Update
If this copy/paste is accurate, you have this:
"CA: " ^ string_of_int sum_ca ^ "\n" ^)
There's a strange ^ operator at the end of the string expression.
In your code I see a self value which is never defined in the snippet you gave us.
I think somewhere before you are defining an object as something like let blabla = object(self) and you forgot to close if with the end keyword.
Related
The following is getting an error:
(* Greetings, Earthlings! *)
fun greeting (some_name : string option) =
"Hello there, " ^
(if isSome some_name
then valOf some_name
else "you")
^ "!"
greeting("Tom")
The error is:
> $sml < main.sml
Standard ML of New Jersey v110.78 [built: Thu Aug 31 03:45:42 2017]
- = stdIn:3.5-9.16 Error: operator is not a function [tycon mismatch]
operator: string
in expression:
"!" greeting
I can't figure out where there is a type mistmatch.
Don't forget semi-colon after "!". SML assumes here that greeting("Tom") is part of the function. So it interprets "!" greeting as a function call.
Also your function argument is a string option so don't forget the SOME around "Tom". Here is the corrected code:
fun greeting (some_name : string option) =
"Hello there, " ^
(if isSome some_name
then valOf some_name
else "you")
^ "!";
print (greeting (SOME "Tom") ^ "\n");
print (greeting NONE ^ "\n");
Personally, I prefer using pattern matching in that situation, as it enhances readability in my opinion:
fun greeting (some_name : string option) =
"Hello there, " ^
(case some_name
of NONE => "you"
| SOME name => name)
^ "!";
This function is incidentally corresponds to the two-fer exercise of Exercism.io. Since my two favourite variants have not been show, I'd like to suggest either pattern matching directly in the argument of greeting or using a library function:
fun greeting NONE = "Hello there, you!"
| greeting (SOME name) = "Hello there, " ^ name ^ "!"
fun greeting name =
"Hello there, " ^ Option.getOpt (name, "you") ^ "!"
A reason for liking the first one is that it uses case-matching just like case-of, but with less syntax. And a reason for liking the second one is that it avoids duplication of the part of the string that is the same, and does so using library functions, so you can expect readers to have seen this before.
I have a type record:
type record = { first : string; second : string list; third : string }
I want to extract data from it using match...How would I do that?..
Please let me know. Thanks!
You can match the whole record:
match my_record with
| { first = "something"; } -> do_something
| { second = hd :: tl; third = "something else"; } -> do_something_else
(* ... *)
or target specific fields in it with the dot notation:
match my_record.second with
| hd :: tl -> do_something
(* ... *)
It is also possible to destructure a record in a function with a syntactic shortcut called field punning:
let fun_example { first; third; _ } =
"This is first: " ^ first ^ " and this is third: " ^ third
or by providing aliases for the fields:
let fun_example_2 { first = f; third = t; _ } =
"This is first: " ^ f ^ " and this is third: " ^ t
The underscore ; _ in the pattern is used to tell the compiler it shouldn't worry about incomplete matches when the #warnings "+9" directive is turned on in the toplevel. It may be omitted depending on your style.
For more intricate details please refer to RWO, there's a great chapter on records!
I am trying to append a string to an existing string.
I came across this thread here which explains it.
Just for reference I am pasting the content here from that page
let (^$) c s = s ^ Char.escaped c (* append *)
let ($^) c s = Char.escaped c ^ s (* prepend *)
Now I wanted to know what does (^$) mean in
let (^$) c s = s ^ Char.escaped c (* append *)
This page here states that
operator ^ is for string concatenation
what is (^$) ?
#icktoofay is correct, this code:
let (^$) c s = s ^ Char.escaped c
is defining a new operator ^$.
You can use an operator as an ordinary (prefix) function name by enclosing it in parentheses. And, indeed, this is what you do when you define an operator.
$ ocaml
OCaml version 4.02.1
# (+) 44 22;;
- : int = 66
# let (++++) x y = x * 100 + y;;
val ( ++++ ) : int -> int -> int = <fun>
# 3 ++++ 5;;
- : int = 305
Infix operators in OCaml start with one of the operator-like characters =<>#^|&+-*/$%, then can have any number of further operator-like characters !$%&*+-./:<=>?#^|~. So you can have an infix operator $^ or $^??#+ and so on.
See Section 6.1 of the OCaml manual.
It is to append the given character to the string with escaping:
'x' ^$ "hello" ----> "hellox"
'\n' ^$ "hello" ----> "hello\\n"
Lets say I have a list of type integer [blah;blah;blah;...] and i don't know the size of the lis and I want to pattern match and not print the first element of the list. Is there any way to do this without using a if else case or having a syntax error?
because all i'm trying to do is parse a file tha looks like a/path/to/blah/blah/../file.c
and only print the path/to/blah/blah
for example, can it be done like this?
let out x = Printf.printf " %s \n" x
let _ = try
while true do
let line = input_line stdin in
...
let rec f (xpath: string list) : ( string list ) =
begin match Str.split (Str.regexp "/") xpath with
| _::rest -> out (String.concat "/" _::xpath);
| _ -> ()
end
but if i do this i have a syntax error at the line of String.concat!!
String.concat "/" _::xpath doesn't mean anything because _ is pattern but not a value. _ can be used in the left part of a pattern matching but not in the right part.
What you want to do is String.concat "/" rest.
Even if _::xpath were correct, String.concat "/" _::xpath would be interpreted as (String.concat "/" _)::xpath whereas you want it to be interpreted as String.concat "/" (_::xpath).
This function:
let rec foo () =
try
let line = input_line stdin in
(try
Mparser.tex_expr lexer_token_safe (Lexing.from_string line);
print_string ("SUCCESS\n")
with
Mtexutil.Illegal_tex_function s -> print_string ("$T" ^ s ^ " " ^ line ^ "\n")
| LexerException s -> print_string ("$L" ^ line ^ "\n")
| Parsing.Parse_error -> print_string ("$P" ^ line ^ "\n")
| _ -> print_string ("$S " ^ line ^ "\n"));
flush stdout;
foo ();
with
End_of_file -> ()
;;
gives the error:
Warning 10: this expression should have type unit.
for the line starting with Mparser.tex.
How can I resolve this warning?
It seems the compiler is warning you that Mparser.tex_expr returns a value that you're not using. You can get rid of the warning by making it clear that you're throwing the value away purposely. That's what the ignore function is for:
ignore (Mparser.tex_expr lexer_token_safe (Lexing.from_string line));
In some cases I think things read better with let ... in rather than a semicolon:
let _ = Mparser.tex_expr lexer_token_safe (Lexing.from_string line) in
...