Ocaml 断言不触发

Ocaml 断言不触发,ocaml,Ocaml,我试图在OCaml中编写一个递归幂函数,并尝试添加一个断言以确保指数始终大于或等于0 我的代码是 let rec power (x:int) (n:int) : int = assert (n >= 0) if n==0 then 1 else x * (power x (n - 1)) 这给了我一个if中的语法错误。我试过了 let rec power (x:int) (n:int) : int = let () = assert (n >= 0) in

我试图在OCaml中编写一个递归幂函数,并尝试添加一个断言以确保指数始终大于或等于0

我的代码是

let rec power (x:int) (n:int) : int =
  assert (n >= 0)
  if n==0 then 1
  else x * (power x (n - 1))
这给了我一个
if
中的语法错误。我试过了

let rec power (x:int) (n:int) : int =
  let () = assert (n >= 0) in 
    if n==0 then 1
    else x * (power x (n - 1))
(与中所示内容类似)但
断言
从不触发

我到底做错了什么


请注意,我确实想使用
assert
,而不是
failwith
,主要是为了学习。

您的第二个示例很好。最有可能的问题是你测试它的方式

下面是一个演示其工作原理的课程:

$ ocaml
        OCaml version 4.01.0

# let rec power (x:int) (n:int) : int =
  let () = assert (n >= 0) in 
    if n==0 then 1
    else x * (power x (n - 1))      ;;
val power : int -> int -> int = <fun>
# power 3 (-2);;
Exception: Assert_failure ("//toplevel//", 2, 11).
# 
$ocaml
OCaml版本4.01.0
#让rec power(x:int)(n:int):int=
让()在中断言(n>=0)
如果n==0,则为1
else x*(幂x(n-1));;
val功率:int->int->int=
#幂3(-2);;
异常:断言失败(“//toplevel//”,2,11)。
# 
更新

正如camlspotter所指出的,如果在断言和其余部分之间添加分号,则第一个示例也可以:

$ ocaml
        OCaml version 4.01.0

# let rec power (x:int) (n:int) : int =
  assert (n >= 0);  (* <--  Semicolon here *)
    if n==0 then 1
  else x * (power x (n - 1))
    ;;
val power : int -> int -> int = <fun>
# power 2 3;;
- : int = 8
# power 2 (-3);;
Exception: Assert_failure ("//toplevel//", 2, 2).
$ocaml
OCaml版本4.01.0
#让rec power(x:int)(n:int):int=
断言(n>=0);(*int->int=
#权力2 3;;
-:int=8
#幂2(-3);;
异常:断言失败(“//toplevel//”,2,2)。

断言(n>=0)
之后放置
的第一个代码fogot;
。当
n<0
时应触发该代码

顺便说一句

有趣的是,
assert
不是一个函数,它对太多参数的应用不会导致类型错误,而是语法错误,初学者可能很难理解

failwith
是一个函数,同样的错误会更准确地报告(但作为警告):


原因
assert
不是类型为
bool->unit
的正常函数,我不确定,但我猜是因为
assert false
经过特殊处理和编译,在不查看参数的情况下立即引发断言失败。

您忘记了分号:assert(n>=0);是的,我的猜测是,
assert false
也会被特别处理,因为当没有启用assert时,这些特定的断言实际上会被保留。
# failwith;;
- : string -> 'a = <fun>
# failwith "hello" 1;;
Characters 17-18:
Warning 20: this argument will not be used by the funciton.
# assert;;
        ^^
Error: Syntax error
# assert true true;;
              ^^^^
Error: Syntax error