2013-02-03 183 views
0

我想在Haskell中使用递归。我定义:Haskell:如何总结函数列表?

pf:: Int -> Int 
pf 1 = 1 
pf n = pf 1 + sum[pf 1..pf n-1] 

但总和是不正确的!总结一系列功能的正确方法是什么?

+2

你正在求和的列表包括'INT',而不是函数。也不清楚你想达到什么,即你想要什么“正确”。 – gspr

+4

另请注意,'pf n-1'意味着'(pf n)-1',**而不是**'pf(n-1)'。 – dave4420

回答

6

[pf 1..pf (n-1)][pf 1, pf 2, pf 3, ..., pf (n-1)]不一样。

> let f x = 2^x 
> [f 1 .. f 4] 
[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 
> [f 1, f 2, f 3, f 4] 
[2,4,8,16] 

你可能想map

pf n = pf 1 + sum (map pf [1..n-1]) 

而且,正如此言,pf x = 2^(x-1)

+0

明白了,非常感谢你! –

+1

@CharlieVictor然后将答案标记为“接受”,我们都将过着幸福的生活:) – Artyom

+0

我想知道我是怎么做的?1 –

0

与接受的答案开始,我们可以做以下细化

pf n = pf 1 + sum (map pf [1..n-1]) 

我们有心心PF 1,那么它只是一个总和
通常的和可以使用倍作为后续

明示
sum = fold (+) 0 

这里0可以是视图和的种子,以说服输入以下两个在ghci中表达

foldl (+) 10 [1..10] -- return 65 
10 + sum [1..10] -- return 65 too 

在我们的例子中,种子等于PF 1,这导致我们

pf n = foldl (+) (pf 1) (map pf [1..n-1]) 

同样,我们可以重写一个术语,这次我将重点放在列表范围[1..N-1]

enumFromTo 1 (n-1) = [1..n-1] 

或N-1可能是重写(再次)作为预解码n,那么我们有

enumFromTo 1 (pred n) = [1..n-1] 

在马代在表达,我们得到

pf n = foldl (+) (pf 1) (map pf (enumFromTo 1 (pred n))) 

现在我们可以表达点自由风格的主要表现

pf = foldl (+) (pf 1) . map pf . enumFromTo 1 . pred 

我们可以做更多的考虑比图能折叠的期限是明示的,但我们肯定会在可读性丢失,只需注意,

map f = foldl (\x xs -> f x : xs) [] 
+0

'map f = foldr ...',而不是foldl。 –