OCaml无效参数(“等于:抽象值”)

时间:2013-02-18 04:54:19

标签: ocaml refs

似乎我无法为ref指定一个抽象值,我不知道该怎么做。

open Big_int
let largest = ref zero_big_int;;
let depth = ref zero_big_int;;
let rec big i = (add_int_big_int i zero_big_int)
and collatz = fun num depth ->
  print_endline (string_of_big_int num);
  (if(eq_big_int  (add_int_big_int (-1) num) zero_big_int)then(depth)else(
    if eq_big_int (mod_big_int num (big 2)) zero_big_int then (collatz (div_big_int num (big 2)) (succ_big_int depth)) else (collatz (succ_big_int (mult_int_big_int 3 num)) (succ_big_int depth))))
and euler14 i =
  print_endline (string_of_big_int i);
  (if(lt_big_int i (big 1000000))then (
    let ret = (collatz i unit_big_int) in
    if(ret> !depth)then (largest:=i;depth:=ret; (euler14 (succ_big_int i))) else (euler14 (succ_big_int i))
  ) else (!largest));;
print_endline (string_of_big_int (euler14 (big 2)));;

当我尝试最大值时代码似乎崩溃:= i和depth:= ret这两个都是Big_nums。有没有办法解决这个问题?

2
2
1
3
3
10
5
16
8
4
2
1
Fatal error: exception Invalid_argument("equal: abstract value")

2 个答案:

答案 0 :(得分:5)

您无法将Big_int.big_int类型的值与多态=>>=进行比较。相反,您必须为包含Big_int.big_int的所有类型编写自己的比较函数,即使它是深度嵌入的。

使用OCaml 3.12.1或更高版本,您可以使用外部库Zarith中实现的类型为Z.t的值的多态比较函数,这是Big_int的现代替代品。

与多态操作兼容只是Zarith优于Big_int的优势之一。它的内存也更紧凑,速度更快。

答案 1 :(得分:0)

失败的事情似乎是多态比较ret > !depth,而不是对ref的赋值。我认为你可以使用Big_int.compare_big_int

# let x = big_int_of_int 3;;
val x : Big_int.big_int = <abstr>
# let y = big_int_of_int 4;;
val y : Big_int.big_int = <abstr>
# x > y;;
Exception: Invalid_argument "equal: abstract value".
# compare_big_int x y;;
- : int = -1
# 

(多态比较是OCaml中的一个敏感点。)