我正在 OCaml 中编写一个函数,该函数读取字符串,验证它是否是整数并将其转换为整数,然后检查它是否包含在范围 [a,b] 内。验证工作正常,但我需要该函数最终返回数字。
let string_is_int s =
try int_of_string s |> ignore; true
with Failure _ -> false
let num_between a b = (
let x = ref 0 in (
(*validation loop*)
let op = ref false in
while not !op do
let x_string = read_line () in
if string_is_int x_string then (
let x_int = int_of_string x_string in
if x_int>=a && x_int<=b then (
op := true;
x := x_int;
)
else
Printf.printf "Invalid, enter again: ";
)
else
Printf.printf "Invalid, enter again: ";
done
)
)
let n = num_between 1 4;;
我尝试在 while 循环末尾的括号后面添加“x”和“!x”,但出现错误
This expression has type unit
This is not a function; it cannot be applied.
我知道 OCaml 没有关键字“return”。验证循环完成后如何返回 x?
您的基本问题是 OCaml 中的
while
循环不返回值。它总是返回 ()
,称为“单位”。
解决此问题的一种方法是编写自己的显式递归函数来返回所需的值。
另一种方法是将结果放在可以从循环外部访问的地方。事实上,你已经在这样做了。你只需要在最后添加这个:
done;
!x
如果您想尝试减少所使用的引用数量,您可以查看此函数,该函数返回它发现的第一个既是正方形又是回文数的 3 位数字:
let look () =
let is_palindrome k =
let s = string_of_int k in
let slen = String.length s in
let srev = String.init slen (fun i -> s.[slen - i - 1]) in
s = srev
in
let rec loop k =
if is_palindrome (k * k) then
k * k
else
loop (k + 1)
in
loop 10
欢迎来到 Stack Overflow!
这对我来说效果很好:
let num_between a b =
let x = ref 0 in (
(*validation loop*)
let op = ref false in
while not !op do
let x_string = read_line () in
if string_is_int x_string then (
let x_int = int_of_string x_string in
if x_int>=a && x_int<=b then (
op := true;
x := x_int;
)
else
Printf.printf "Invalid, enter again: ";
)
else
Printf.printf "Invalid, enter again: ";
done
);
!x
它只是在
!x
循环结束后的括号后面添加 while
。您可能尝试将其放在错误的右括号之后(包含整个函数体的右括号,这是不需要的,我在这里将其删除;事实上,甚至不需要我留在此处的最外面的括号),或者也许您忘记了分号 ;
将 !x
与前面的表达式分开。
作为对此的补充,根本不需要使用 OCaml 的任何命令式功能来解决这个问题。我们只需要递归。退出情况将成功读取指定范围内的 int。
let read_int_between a b =
match int_of_string_opt @@ read_line () with
| Some n when n >= a && n <= b -> n
| _ -> read_int_between a b