我一直在研究完美的数字,我在 rosettacode 上发现了一段有趣的代码:
perfect n = n == sum [i | i <- [1..n-1], n `mod` i == 0]
现在,我了解什么是完美数字,并且我知道哪些数字被认为是完美的,但是我正在努力弄清楚这段代码的哪些部分做了什么。
我知道它正在计算输入数字的因素,并将它们组合在一起以查看它是否与输入本身匹配,但我不确定它是如何做到的。
如果有人能以对初学者友好的方式分解这段代码,我将不胜感激。
我一直在研究完美的数字,我在 rosettacode 上发现了一段有趣的代码:
perfect n = n == sum [i | i <- [1..n-1], n `mod` i == 0]
现在,我了解什么是完美数字,并且我知道哪些数字被认为是完美的,但是我正在努力弄清楚这段代码的哪些部分做了什么。
我知道它正在计算输入数字的因素,并将它们组合在一起以查看它是否与输入本身匹配,但我不确定它是如何做到的。
如果有人能以对初学者友好的方式分解这段代码,我将不胜感激。
n == sum [i | i <- [1..n-1], n `mod` i == 0]
^^^^^^^^^
对于i
从1
到n-1
(即[1, 2, 3, 4 ... n-1]
)
n == sum [i | i <- [1..n-1], n `mod` i == 0]
^^^^^^
并且仅适用于那些均分的i
值n
。丢弃不符合此要求的值。
n == sum [i | i <- [1..n-1], n `mod` i == 0]
^^^
包括i
在结果列表中。
n == sum [i | i <- [1..n-1], n `mod` i == 0]
^^^^
将此列表的元素添加在一起。
n == sum [i | i <- [1..n-1], n `mod` i == 0]
^^^^
并且True
当总数等于时返回n
。
[i | i <- [1..n-1], n `mod` i == 0]
从中间开始,你可以这样读:对于列表的每个元素i
,[1..n-1]
检查是否n `mod` i
等于0
。如果是,则包含i
在结果列表中(即 . 左侧的部分|
。不使用列表理解语法,可以使用以下filter
函数编写:
filter (\i -> n `mod` i == 0)
然后将结果列表的元素与 相加sum
,最后,测试总和是否与 相等n
。