如何使用有理元素创建列表

时间:2014-05-20 18:48:25

标签: haskell

我尝试以下方法。函数 cant :: Int - > Rational应该给出Rational类型列表的第n个元素。

特别是,列表以元素1/1开头,并具有以下属性: (假设a / b是分数,构造有理数我使用模块Data.Ratio中的运算符%。所以对于a / b,写一个%b。而gcd是给出最大公约数的函数)

if(a-b)==0                       then a % (a+b)
if (a-b)<0 && a+1/= b+1          then (a+1) % (b-1)
if (a-b)>0 && (gcd a b = a || b) then (a-b) % (a+b)

所以,例如,正如我所说:当我以a / b = 1/1开始。因为1-1 = 0,那么列表的第二个元素将是1/2。 然后我将采用第二个元素1 / 2.因为1-2 = -1&lt; 0 1 + 1 / = 2 + 1,那么列表的第3个元素将是2/1。 然后我会采取2/1,依此类推......

所以,我的想法是构建一个以1%1开头的列表,所以像

[(1%1)..]  

并取第一个确实是(1%1)的元素并使用上述条件创建第二个元素,但[(1%1)..]不起作用。 (我怎么来[(1%1)..]:在某些网站上,我看到[1,2,3,4等等]的符号[1 ..],我教[(1%) 1)..]它会是相同的)

我还没有找到其他想法。有人可以给我另一种策略吗?请不要代码,因为我想学习它,所以只有你的想法才会完美...... xD

编辑: 你好,谢谢你的回答。 Collat​​z的例子给了我很多帮助。但对于解决方案,我使用另一个想法。现在,我写下以下内容:

import Data.Ratio

list :: [Rational]
list = initial : map calculateNext list


calculateNext :: Rational -> Rational
calculateNext (a%b)                   | (a-b) == 0                     = a % (a+b)
                  | (a-b)<0 && (a+1) /= (b-1)      = (a+1)%(b-1)
                  | (a-b)>0 && (gcd a b == a || b) = (a-b)%(a+b)


initial :: Rational
initial = (1%1)

但是编译器说:

calculate.hs: 8:1:Parse error in pattern: calculateNext

我认为它无法理解,我试图用a%b的论点来表达...?我对吗? 如果是的话,怎么解决它才能理解呢?

2 个答案:

答案 0 :(得分:4)

您可能希望this blog post,并且您可以在positiveRationals function提供的universe package中查看相应提示的实现。 ((+++)辅助函数的定义给出了here。)

要完全按 的要求,我建议您查看iterate函数。将您建议的算法写为一个函数,只需一步,然后将该函数传递给iterate,它将为您运行所有步骤。这是一个类似算法的例子,可以让您了解我的意思。而不是理性,我们将做Collat​​z序列 - 它类似,但足够不同,它不包含剧透。

Collat​​z序列如下:要进行下一步,如果数字是偶数,则除以2;否则,将它加倍并添加一个。在代码中,

collatzStep n
    | even n    = n `div` 2
    | otherwise = 3 * n + 1

collatz n = iterate collatzStep n

你可以通过在ghci:

中运行来看到从30开始的Collat​​z序列
*Main> take 10 (collatz 30)
[30,15,46,23,70,35,106,53,160,80]

答案 1 :(得分:3)

这可以通过简单的递归模式实现:

list = initial : map calculateNext list

在这种情况下,initial == 1 % 1calculateNext将是您使用if语句概述的代码。