我正在用F#练习。我正在尝试创建一个简单的程序,能够找到几个素数,总和,等于自然数输入。这是哥德巴赫猜想。一对素数就足够了。我们假设输入为偶数。
我首先创建了一个函数来检查数字是否为素数:
'!!!' {
'Tillykke du har vundet 50 dollarz'
$vundet+= 50
$history += 'Tillykke du har vundet 50 dollarz'
}
然后,我试图开发一个函数,(a)查找素数,(b)将它们的和与输入'z'进行比较,(c)在找到两个数字时返回一个元组。该功能不应该是正确的,但我会得到这个问题背后的原因:
let rec isPrime (x: int) (i: int) :bool =
match x % i with
| _ when float i > sqrt (float x) -> true
| 0 -> false
| _ -> isPrime x (i + 1)
问题:即使我指定输出应该是元组let rec sumPrime (z: int) (j: int) (k: int) :int * int =
match isPrime j, isPrime k with
| 0, 0 when j + k > z -> (0, 0)
| 0, 0 -> sumPrime (j + 1) (k + 1)
| _, 0 -> sumPrime j (k + 1)
| 0, _ -> sumPrime (j + 1) k
| _, _ -> if j + k < z then
sumPrime (j + 1) k
elif j + k = z then
(j, k)
编译器抗议,声称预期输出应该是:int * int
类型。遇到麻烦时,我通常会提到我喜欢的F# for fun and profit,但这次我找不到问题所在。任何建议都非常感谢。
答案 0 :(得分:4)
您的代码有三个我发现的问题:
您的isPrime
会返回bool
(正如您指定的那样),但match
中的sumPrime
表达式与整数相匹配(在F#中) ,布尔值false
不与整数值0
相同。您的match
表达式应如下所示:
match isPrime j, isPrime k with
| false, false when j + k > z -> (0, 0)
| false, false -> ...
| true, false -> ...
| false, true -> ...
| true, true -> ...
if...elif
案例中有true, true
个表达式,但没有最终else
。默认情况下,else
表达式的最终if
会返回()
类型unit
。因此,一旦您解决了第一个问题,您就会发现F#抱怨int * int
和unit
之间的类型不匹配。您需要在最终匹配案例中添加else
条件,以说明如果j + k > z
该怎么做。
您反复调用sumPrime
函数,该函数只需两个参数即可获取三个参数。这在F#中是完全合法的,因为它是一种俗语:用两个参数调用sumPrime
会产生类型int -> int * int
:一个函数,它接受一个int
并返回一个元组int
秒。但那不是你真正想做的事情。确保在所有递归调用中为z
指定值。
通过这三项更改,您可能会看到编译器错误消失。