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

时间:2018-02-22 15:34:07

标签: pattern-matching ocaml

我正在尝试在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,因此它应该返回{{1} } ...

2 个答案:

答案 0 :(得分:5)

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

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关键字。

答案 1 :(得分:2)

我建议您阅读the pattern documentation。简而言之,模式必须是常量,以便OCaml编译器可以有效地优化它们。如果要评估实际谓词而不仅仅是构造函数匹配,则必须使用when子句。

@glennsl提出的if / else的另一种替代方法,即IMHO在函数式语言中总是看起来很奇怪,你可以匹配比较的实际结果:

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