考虑print in with block作为返回值



当我想返回布尔值时,我遇到了一个问题,但我总是得到错误(下面的代码)

错误:该表达式具有类型unit,但期望的是类型bool

method addVehicle licensePlate : bool = 
let isSuccess = ref false in
try
(* get current time to make sure unique id *)
id <- int_of_float (Unix.time ());
(* ask to what kind of vehicle to input *)
let kind = ref 0 in 
let quit_loop = ref false in
while not !quit_loop do
print_string "What kind of vehicle: {0-Car, 1-Motobike, 2-Wheelchair, -1-Exit}? ";
kind := read_int ();
if !kind == 0 then 
(vehicle <- new car licensePlate 60;
quit_loop := true;)
else  if !kind == 1 then
(vehicle <- new car licensePlate 60;
quit_loop := true;)
else if !kind == 2 then
(vehicle <- new wheelchair licensePlate 60;
quit_loop := true;)
else if !kind == -1 then
quit_loop := true
else 
print_endline "Invalid vehicle!"

(* match !kind with
|  0 -> vehicle <- new car licensePlate 60;        quit_loop := true;
|  1 -> vehicle <- new motorbike licensePlate 60;  quit_loop := true;
|  2 -> vehicle <- new wheelchair licensePlate 60; quit_loop := true;
| -1 -> quit_loop := true;
|  _ -> print_endline "Invalid vehicle!"; *)
done;
(* ask start time *)
if not (!kind == -1) then 
let quit_loop = ref false in
while not !quit_loop do
print_string "Input start time (format yyyy-MM-dd hh:mm): ";
let input = read_line () in 
try
let (year, month, day, hour, minute) = sscanf input "%d-%d-%d %d:%d" (fun x y z t w -> (x, y, z, t, w)) in
startTime <- snd (mktime { 
tm_sec = 0; tm_min = minute; tm_hour = hour; tm_mday = day; 
tm_mon = month - 1; tm_year = year - 1900; tm_wday = 0; tm_yday = 0; tm_isdst = false;
});
quit_loop := true;
isSuccess := true;
with
| _ -> print_string "Invalid start time!";
done;
with
| _ -> print_string "Something went wrong when adding vehicle";
match isSuccess with
| _ -> !isSuccess;

我想解决这个问题,使我的方法返回布尔值!

首先,OCaml中的等式为=,如果ab不是可变值,则不指定结果a == b。你想写a=b.

第二,你误用了;:;在OCaml中不是终止符,它是一种二进制运算符。

第三,你的缩进是在欺骗你。你的代码读作

with
| _ -> 
(print_string "Something went wrong when adding vehicle";
match isSuccess with
| _ -> !isSuccess)

,当你可能想写

(try ...
with
| _ -> print_string "Something went wrong when adding vehicle"
);
match isSuccess with
| _ -> !isSuccess

第四,我建议将你的方法拆分为分隔良好的函数:这将使早期发现编程和语法错误变得容易得多。特别是,应该尽可能避免使用宽try ... with ...子句,因为它隐藏了异常的来源。

作为octachron答案的补充,考虑一个简单的函数,它允许您提示车辆类型。非常简单的尾部递归,当输入与提供的任何选项都不匹配时发生。

let rec prompt_for_vehicle_type () =
print_string "What kind of vehicle: {0-Car, 1-Motobike, 2-Wheelchair, -1-Exit}? ";
let kind = read_int () in
match kind with
| -1 | 0 | 1 | 2 -> kind
| _ -> 
print_endline "Invalid vehicle!";
prompt_for_vehicle_type ()

现在,我可以简单地调用这个函数,而不是在我的程序的主逻辑中创建一个循环,它将只返回一个有效的选择,然后可以对该选择进行模式匹配以确定如何继续。

# prompt_for_vehicle_type ();;
What kind of vehicle: {0-Car, 1-Motobike, 2-Wheelchair, -1-Exit}? 4
Invalid vehicle!
What kind of vehicle: {0-Car, 1-Motobike, 2-Wheelchair, -1-Exit}? 7
Invalid vehicle!
What kind of vehicle: {0-Car, 1-Motobike, 2-Wheelchair, -1-Exit}? 2
- : int = 2
# 

在另一个层面上,我们可以使用模块对其进行泛化,并添加限制尝试次数的功能。由于在没有有效选择的情况下可能会达到限制,因此函数应该返回一个选项类型。

module Q = struct
module M = Map.Make (String)
let rec prompt_n n msg err opts =
if n < 0 then None
else (
print_endline msg;
M.iter (Printf.printf "%s. %sn") opts;
let input = read_line () in
if M.mem input opts then Some input
else (
print_endline err;
prompt_n (n-1) msg err opts
)
)
end

并尝试调用10次:

Q.prompt_n 10 "What kind of vehicle?" "Invalid vehicle!"
Q.M.(empty |> add "0" "Car" |> add "1" "Motobike" 
|> add "2" "Wheelchair" |> add "-1" "Exit")

下一个级别是使用函子抽象出输入的类型,例如,我们可以像提示int型一样轻松地提示字符串。

module type Q_SIG = sig
type t
val compare : t -> t -> int
val input : unit -> t
val print : t -> unit
end
module Q (S : Q_SIG) = struct
module M = Map.Make (S)

type key_t = S.t

let rec prompt_n n msg err opts =
if n < 0 then None
else (
print_endline msg;
M.iter (fun k v -> S.print k; Printf.printf ". %sn" v) opts;
let input = S.input () in
if M.mem input opts then Some input
else (
print_endline err;
prompt_n (n-1) msg err opts
)
)
end
let module P = Q(struct 
type t = int 
let compare = compare 
let input = read_int 
let print = print_int 
end) in
P.prompt_n 10 "What kind of vehicle?" "Invalid vehicle!"
P.M.(empty |> add 0 "Car" |> add 1 "Motobike" 
|> add 2 "Wheelchair" |> add ~-1 "Exit")

最新更新