2013-02-19 39 views
2

在我的测试考试中,一个问题是,这个方法做了什么。Haskell:这个方法做什么

dos a = ([x | x <- [2..div a 2], mod a x == 0] == [])

我是新来的Haskell,但据我可以说,它会检查如果dos a = ([x | x <- [2..div a 2], mod a x == 0])结果是一个空列表。另外x是a除以2的所有数字,其中%数字== 0.因此,这是所有偶数?它似乎检查数字是否可以通过2分割,如果是 - > false,否则返回。任何人都可以向我详细解释语义吗?

+8

找出最好的方法是打破多个函数中的表达式,并在REPL中评估它们。 '[2..div a 2]'返回从2到a/2的整数列表。 – Simon 2013-02-19 16:13:56

回答

9

你已接近正在发生的事情。有几个组件要理解。

首先,[2 .. div a 2]生成一个数字列表,从2到floor(a/2)

接着,mod a x == 0滤除值从2至floor(a/2)其中 除法a(例如它找到的a所有因素)。 因此,通过

[x | x <- [2 .. div a 2], mod a x == 0] 

生成的列表中包含了所有分a的数字。

最后,== []检查 此列表为空(例如a没有因素)。那么,究竟该函数实际上 所做的是确定一个数是否是试图 产生的因素,这是很容易素时看到您使用dos作谓语 的过滤器:

Prelude> let dos a = ([x | x <- [2..div a 2], mod a x == 0] == []) 
Prelude> :t dos 
dos :: Integral t => t -> Bool 
Prelude> filter dos [2 .. 100] 
[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97] -- Prime goodness 
6

它是检查数字是否为素数的基本算法。它遍历从2a/2的所有数字,并检查它是否有任何分开a,如果列表为空,则表示它没有2a/2之间的因子,这意味着数字是素数。

+0

这个算法是* bad *。只需要检查数字是否可以被**的平方不大于数字的**素数**整除。 – Ingo 2013-02-19 19:26:20

+0

@Ingo我不是在说这个算法。这是他考试中提出的问题,所以我只是解释它的作用。你不能在考试中回答问题“你的算法不是最优的,所以我不会回答这个问题”。 – Satvik 2013-02-20 04:33:19

+2

我知道,我只是想提一下它,以免有人认为这是一个愚蠢的功课问题算法。 – Ingo 2013-02-20 07:18:11