几乎是直接翻译的python代码链接。
首先我们需要定义一个gcd 函数,使用递归作为“循环构造”而不是python while(FP 更“面向递归”)
let rec gcd = function
| x, 0 -> x
| x, y -> gcd (y, x % y)
剩下的就是 coprime 函数来定义哪个可以在 pointfree 样式中轻松完成,方法是组合前面的 gcd 函数,部分应用与 1 的相等性
let coprime = gcd >> (=) 1
功能相同:
let coprime (x, y) = gcd (x, y) = 1
除此之外,我们可以通过一些调整使代码更通用(关于数字类型),尽管我不确定这是否值得
(例如,在操作 bigint 时可能更喜欢使用BigInteger.GreatestCommonDivisor)
open LanguagePrimitives
let inline gcd (x, y) =
// we need an helper because inline and rec don't mix well
let rec aux (x, y) =
if y = GenericZero
then x
else aux (y, x % y)
aux (x, y)
// no pointfree style, only function can be inlined not values
let inline coprime (x, y) = gcd (x, y) = GenericOne
来自@Henrik Hansen 的答案是一个更新版本,计算出active pattern 以提高可读性并提取常见行为
let (|LT|EQ|GT|) (x, y) =
if x < y then LT
elif x = y then EQ
else GT
let areCoPrimes x y =
let rec aux (x, y) =
match x, y with
| 0, _ | _, 0 -> false
| LT -> aux (x, y - x)
| EQ -> x = 1
| GT -> aux (x - y, y)
aux (abs x, abs y)