This expression has type processor_return_type but an expression was expected of type unit - ocaml

I now have a function called processor, inside the processor function, a list will be matched to different patterns. In some patterns I wish it to return a tuple while the rest calls processor again.
Suppose I now have a custom type to wrap two types of processor:
type processor_return_type =
| REC of unit
| INFO of (string list * bool)
My processor basically looks like this:
let rec processor cmds stack env =
match (cmds, stack) with
| (ADD::rest_cmds, first_list::rest_stack) -> ... processor a b c
...
| (FUN::...) -> ... let (sl, b) = processor a b c in processor d e f
| (RETURN::...) -> (string list, a bool)
| _ -> REC()
...
in
Then I invoke this function with (you can assume I give correct arguments):
processor cmd_list [[]] [[]];;
The error emerges:
664 | processor cmd_list [[]] [[]];;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: This expression has type processor_return_type
but an expression was expected of type unit
How could I fix this issue?

Thanks for including the error message and the indicated erroneous part of the code.
The expression that the compiler is complaining about is the entire call to processor. In other words, the reason the compiler is expecting something of type unit is because of the context of the call, which you unfortunately don't show.
Generally your code should expect to get a result back from the call to processor and should handle the result appropriately. If there are other branches of your code (the else part of an if, say), they have to be of the same type also.
Here's an example of an erroneous call context:
if some_test () then
Printf.printf "did not want to call processor\n"
else
proceessor ...
If you show more of the context of the call, people can give you a more helpful answer maybe.

Related

SML getting an unbound variable or constructor error when everything seems right

I'm trying to figure out mutual recursion. I have this code:
fun take(L)=
if L=nil then nil
else hd(L) :: skip(tl(L))
AND
fun skip(L)=
if L=nil then nil
else take(tl(L));
but it gives me these errors:
stdIn:54.14-54.18 Error: unbound variable or constructor: skip
stdIn:55.1-55.4 Error: unbound variable or constructor: AND
What am I doing wrong?
Your immediate error is because Standard ML is case-sensitive, and all of its reserved words are in lowercase; so you need to write and rather than AND.
Additionally, fun introduces an entire declaration, not an individual binding, meaning that you need to remove the extra fun after and.
Lastly, your functions currently require the list to have an equality type (such as int list or string list), which may not be a deal-breaker, but given what the functions actually do, there's really no reason they can't support non-equality types such as real list. To achieve that, you should match the parameter against the pattern nil, instead of testing whether the parameter equals nil. (More generally, you should use pattern-matching in more places; you have no reason to call hd and tl.)
Putting it together:
fun take nil = nil
| take (h::t) = h :: skip t
and skip nil = nil
| skip (h::t) = take t

why the use of _ prevent having warnings

I have the following code (it's a test so it does nothing interesting)
let test k =
let rec aux = function
|0 -> 0
|z when z = 2 -> raise Exit
|_ -> aux (k-1)
in try let _ = aux k in true
with Exit -> false
At the end there is the use of the syntax : let _, to me it's just a syntax when you don't have an idea of a name you can use to define your function.
Yet if I do the following :
let test k =
let rec aux = function
|0 -> 0
|z when z = 2 -> raise Exit
|_ -> aux (k-1)
in try let b = aux k in true
with Exit -> false
I get a warning like : "variable b is unused", I don't understand why there is a difference between let _ and let b ?
For example I know that when dealing with unit type it's common to use the syntax : let (). Yet I don't have any warning when doing :
let b = print_int 2
even if I am not using :
let () = print_int 2
So what is particular with let _ ?
Thank you !
This is a convention, recognized by the compiler, to indicate that you're not going to use the result of a computation, e.g.,
let a = 5 + 6 in
()
will (or will not, depending on your warning settings) trigger the unused variable warning, since you clearly bound the result to a variable a, but not using it in the rest of your computation. In imperative languages it is quite common, to compute expressions for their side effects and ignore produced values if any. Since OCaml is a functional language, in which values are used to produce values, it usually an indicator of an error, when you forgot to use a bound variable.
Therefore, to explicitly tell the compiler that you're ignoring the value, you may start your variable with the underscore, e.g.,
let _unusued = 5 + 6 in
()
You can just use a wild pattern _ (which also starts with the underscore).
You have a warning with your second code because you define the variable b containing a value and you do not use it after.
The best use if you do not want to use the result of any expression is to discard its result using the 'let _ =' construct (it tells you want the expression to be evaluated, for potential side effects, but do not care to keep its result).
For the second part of your question, I think there are different rules related to the top loop, so the behaviours may not be comparable. In the first part, you define b inside a function and in the second part, you define b inside the top loop. In the top loop, you may define variables you will not use without getting a warning.

Error: This expression has type unit but an expression was expected of type inst list

|ScmOp(g,h) ->newList := (createInstList **!newList** a currentReg);
This is our code, we received the above error when compiling. The error comes from the !newList parameter we send to the recursive function. newList is defined as a reference so we sent !newList in order to pass its value. When removing the ! we received an error that we sent a ref for inst list instead of an inst list (eventually we want to send an inst list!).
OK, I think the problem is that the compiler thinks createInstList returns unit. This is due to precedence of ;, I think.
It looks to me like the !newlist at the end is supposed to be the result of the whole createInstList function. But I suspect that it's being treated as part of the inner match.
You might try this:
let rec createInstList instList expr currentReg =
let newList = ref instList in
(match
...
done);
!newList

OCaml - Creating a function which prompts for floats and returns a list of floats

I'm teaching myself OCaml and I sometimes need to create a function where I'm not really sure what the proper solution should be. Here's one that I'm a little confused about.
I need a function that will prompt the user for individual float values and return everything entered in a float list. I can create this function but I'm not sure if its the proper/best way to do it in Ocaml.
Here's my attempt.
let rec get_floats() =
match
(
try Some(read_float())
with
| float_of_string -> None
)
with
| None -> []
| Some s -> s :: get_floats();;
This code works buts I'm at a loss deciding if its a 'proper OCaml' solution. Note, to exit the function and return the float list just enter a non-integer value.
(I hope that) this is a simple peephole rewrite involving no thought whatsoever of the function in your question:
let rec get_floats() =
try
let f = read_float() in (* as suggested by Martin Jambon *)
f :: (get_floats())
with
| float_of_string -> []
The idea I tried to apply here is that you do not need to convert the success/failure of read_float into an option that you immediately match: just do what you have to do with the value read, and let the with handle the failure case.
Now that I think of it, I should point out that in both your question and my rewrite, float_of_string is a fresh variable. If you meant to match a specific exception, you failed at it: all exception constructors, like datatype constructors, are Capitalized. You might as well have written with _ -> instead of with float_of_string ->, and a recent version of OCaml with all warnings active should tell you that your function (or mine) binds a variable float_of_string without ever using it.
Thanks everyone for the help. This works.
let rec get_floats() =
try
let x = read_float() in
x :: get_floats()
with
| _ -> [];;
List.iter (fun x -> print_endline(string_of_float x)) (get_floats());;

OCaml Option get

I'm new to OCaml, I'm trying to understand how you're supposed to get the value from an 'a option. According to the doc at http://ocaml-lib.sourceforge.net/doc/Option.html, there is a get function of type 'a option -> 'a that does what I want. but when I type:
# let z = Some 3;;
val z : int option = Some 3
# get z;;
Error: Unbound value get
# Option.get z;;
Error: Unbound module Option
Why isnt this working?
The traditional way to obtain the value inside any kind of constructor in OCaml is with pattern-matching. Pattern-matching is the part of OCaml that may be most different from what you have already seen in other languages, so I would recommend that you do not just write programs the way you are used to (for instance circumventing the problem with ocaml-lib) but instead try it and see if you like it.
let contents =
match z with
Some c -> c;;
Variable contents is assigned 3, but you get a warning:
Warning 8: this pattern-matching is not exhaustive. Here is an example
of a value that is not matched: None
In the general case, you won't know that the expression you want to look inside is necessarily a Some c. The reason an option type was chosen is usually that sometimes that value can be None. Here the compiler is reminding you that you are not handling one of the possible cases.
You can pattern-match “in depth” and the compiler will still check for exhaustivity. Consider this function that takes an (int option) option:
let f x =
match x with
Some (Some c) -> c
| None -> 0
;;
Here you forgot the case Some (None) and the compiler tells you so:
Warning 8: this pattern-matching is not exhaustive. Here is an example
of a value that is not matched: Some None
The usual way to do this is with pattern matching.
# let x = Some 4;;
val x : int option = Some 4
# match x with
| None -> Printf.printf "saw nothing at all\n"
| Some v -> Printf.printf "saw %d\n" v;;
saw 4
- : unit = ()
You can write your own get function (though you have to decide
what you want to do when the value is None).
You should listen to the above posters advice regarding type safety but also be aware that unsafe function such as Option.get (which is available in batteries btw) are usually suffixed with exn. If you're curious this is how Option.get or Option.get_exn could be implemented then:
let get_exn = function
| Some x -> x
| None -> raise (Invalid_argument "Option.get")