如何使用haskell中的范围,元素之间的距离可变

时间:2014-02-23 07:49:24

标签: haskell list-comprehension

我启动了以下代码段,并且我不确定我的错误在哪里。目标是传递两个值valfac,并输出[val1, val1*fac,val1*fac*fac...]形式的列表,但它不起作用。

 gm :: Int -> Int -> [Int]
 gm val fac = let j=0 in
[ if (x==val) then x else if (x==(val+1)) then k else j 
| x <- [val..], let k = val*fac, let j = fac*k]

例如,如果我致电gm 2 3我应该得到结果[2,6,18,54,162...],但我得到的是[2,6,18,18,18...]

3 个答案:

答案 0 :(得分:5)

我觉得您正在尝试将命令式算法直接转换为Haskell。定义这种无限列表的标准方法是使用惰性和递归:

gm val fac = val : gm (val * fac) fac

如果你想使用列表理解:

gm val fac = [val * fac^i | i <- [1..]]

答案 1 :(得分:3)

我认为你可以做到:

gm' val fac = iterate (*fac) val

输出:

*Main> take 5 $ gm' 2 3
[2,6,18,54,162]

您的方法存在的问题是列表理解只能包含三个值val, k, j

答案 2 :(得分:2)

要回答为什么代码不起作用,请记住列表推导中没有可变变量。此表显示了当x valval+1,... {/ p>进展时 x k j x == val? x == val+1? element --------------------------------------------------------- ------- val val*fac fac*k = val*val*fac True False val (x) val+1 val*fac fac*k = val*val*fac False True val*fac (k) val+2 val*fac fac*k = " False False val*val*fac (j) val+3 val*fac fac*k = " False False val*val*fac (j) ... 进展后如何生成列表

k

因此,您可以看到jval不会更改,因为它们是根据常量fac[ 1, fac, fac*fac, fac*fac*fac, ...] 定义的。

这是建议以Haskell方式构建列表的建议。首先构建这个序列:

map (val*)

然后将(*fac)应用于它。

要生成权力序列,有几种方法:

1)它是f x = fac*x 函数的迭代列表。也就是说,定义:

[ 1, f 1, f (f 1), f (f (f 1)), ... ]

然后权力清单是:

iterate

这意味着您可以使用Prelude中的map (*fac)函数。

2)注意,幂序列的尾部是序列的powers x = 1 : map (*x) (powers x) 。因此,您可以写:

{{1}}

这与(1)基本相同,但有时更容易发现序列与其尾部之间的关系。