我正在尝试在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} } ...
答案 0 :(得分:5)
当您使用标识符作为模式时,您将匹配的值绑定到该标识符。与
match b with
| a -> true
您不是将b
与a
进行比较,而是创建新的本地变量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)