我正在尝试在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
您没有将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
关键字,我在上面添加了。
我建议您阅读模式文档。简而言之,模式必须是常数,以便可以通过OCAML编译器有效地优化它们。如果您想评估实际谓词,而不仅要评估构造函数匹配,还必须求助于wher句子。
@glennsl提出的if/else的另一种替代方法,恕我直言在功能性语言中总是看起来很奇怪,您可以匹配比较的实际结果:
match (a mod b = 0),(a=b) with
_,true -> true
true,_ -> false
|_ -> isprime a (succ b)