我想在Haskell中使用递归。我定义:Haskell:如何总结函数列表?
pf:: Int -> Int
pf 1 = 1
pf n = pf 1 + sum[pf 1..pf n-1]
但总和是不正确的!总结一系列功能的正确方法是什么?
我想在Haskell中使用递归。我定义:Haskell:如何总结函数列表?
pf:: Int -> Int
pf 1 = 1
pf n = pf 1 + sum[pf 1..pf n-1]
但总和是不正确的!总结一系列功能的正确方法是什么?
[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)
。
与接受的答案开始,我们可以做以下细化
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) []
'map f = foldr ...',而不是foldl。 –
你正在求和的列表包括'INT',而不是函数。也不清楚你想达到什么,即你想要什么“正确”。 – gspr
另请注意,'pf n-1'意味着'(pf n)-1',**而不是**'pf(n-1)'。 – dave4420