是素数 - 未使用的警告匹配案例,返回true而不是false



我正在尝试在OCAML中发挥功能,该功能说如果一个数字a是素数。

这是功能:

let isprime a b = 
  match b with 
   a -> true
  |_ -> if a mod b = 0 then false else isprime (a)(b+1);;

当我运行时:isprime (4)(2);;说我true,但我不明白为什么,因为在这种情况下,4 mod 2 = 0,因此应该返回false ...

当使用标识符作为模式时,您将匹配的值将其绑定到该标识符。用

match b with
| a -> true

您没有将ba进行比较,而是创建一个新的本地变量a并为其分配b的值。这将永远成功,因此警告_分支未使用。

我建议仅使用if/else

let rec isprime a b = 
  if a = b then
    true
  else if a mod b = 0 then
    false
  else
    isprime a (b+1)

编辑:或者您可以做

let rec isprime a b = 
  match () with
  | _ when a = b -> true
  | _ when a mod b = 0 -> false
  | _ -> isprime a (b+1)

,由于这没有任何实际模式匹配,因此if/else传达了您的工作更好。

注意:您还缺少rec关键字,我在上面添加了。

我建议您阅读模式文档。简而言之,模式必须是常数,以便可以通过OCAML编译器有效地优化它们。如果您想评估实际谓词,而不仅要评估构造函数匹配,还必须求助于wher句子。

@glennsl提出的if/else的另一种替代方法,恕我直言在功能性语言中总是看起来很奇怪,您可以匹配比较的实际结果:

match (a mod b = 0),(a=b) with
  _,true -> true
  true,_ -> false
  |_ -> isprime a (succ b)

最新更新