为什么我的OCaml巴贝奇程序不起作用?



代码:

let babbage = 
let n = read_int in
let current = ref n in
let square = ref !current in
let mul = !current * !current in
while ((square := mul) mod 1000000 != 269696) && (!square < max_int) do
current := !current + 1;
done;
if(!square > max_int) then
print_string "Condition not satisfied before max_int reached."
else print_string "The smallest number whose square ends in 269696 is"; !square

错误:

let mul = !current * !current in
Error: This expression has type unit -> int
but an expression was expected of type int
Hint: Did you forget to provide `()' as argument?

仍在学习,但我想真正知道出了什么问题

编辑#1:这是一个练习练习,要求的类型是unit -> int,它的功能是let babbage () =

错误消息给了您一个很好的提示,但您必须遵循一些赋值才能找到原因。

square最初被赋予current的值(和类型),CCD_4最初被赋予CCD的值,n最初被赋予CC的值。

read_int是函数unit -> int,因此n也将具有类型unit -> intcurrentsquare也是。

如果将错误消息中给出的提示应用于read_int,则问题应该得到解决。(这不是你唯一的问题,但这超出了这个问题的范围。)

作为一个附录,这个问题根本不需要命令式编程。我们可以很容易地使用递归来解决它。我们可以写一个函数babbage,它取一个int并将其递增,直到它找到一个平方以269696结束的数字。

let rec babbage n =
let max = 
Int.max_int 
|> float_of_int 
|> sqrt 
|> int_of_float  
in
let square = n * n in
if n > max then None
else if square mod 1_000_000 = 269696 then Some n
else babbage (n + 1)

这将返回int option,然后您可以对其进行模式匹配,以确定是否找到了数字。

let () =
let n = read_int () in
match babbage n with
| None -> 
print_endline "Condition not satisfied before max_int reached."
| Some n' -> 
Printf.printf 
"The smallest number greater than %d whose square ends in 269696 is %d.n" 
n n'

注:使用|>的表达式等效于:

int_of_float (sqrt (float_of_int Int.max_int))

如果babbage必须具有类型unit -> int,那么我们可以将上述babbage函数中的逻辑放入一个本地作用域函数中——让我们称之为babbage',并调用该函数来完成繁重的工作。

let babbage () =
let rec babbage' n =
let max = 
Int.max_int 
|> float_of_int 
|> sqrt 
|> int_of_float  
in
let square = n * n in
if n > max then None
else if square mod 1_000_000 = 269696 then Some n
else babbage' (n + 1)
in
let n = read_int () in
...

现在,如果babbage必须返回int,我们如何处理它不返回int的情况?在babbage'中,我用option类型处理了这个问题,但这个新类型不能返回,所以唯一的选择是返回像-1这样的无意义值,或者引发异常(现有的标准库Not_found异常似乎是一个合乎逻辑的选择)。

let babbage () =
let rec babbage' n =
let max = 
Int.max_int 
|> float_of_int 
|> sqrt 
|> int_of_float  
in
let square = n * n in
if n > max then None
else if square mod 1_000_000 = 269696 then Some n
else babbage' (n + 1)
in
let n = read_int () in
match babbage n with
| None -> ...
| Some n' -> ...

完成代码是留给读者的练习。

相关内容

最新更新