我启动了以下代码段,并且我不确定我的错误在哪里。目标是传递两个值val
和fac
,并输出[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...]
答案 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
val
,val+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
因此,您可以看到j
和val
不会更改,因为它们是根据常量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)基本相同,但有时更容易发现序列与其尾部之间的关系。