Haskell で再帰を使いたい。私は次のように定義します。
pf:: Int -> Int
pf 1 = 1
pf n = pf 1 + sum[pf 1..pf n-1]
しかし、合計は正しくありません!関数のリストを合計する適切な方法は何ですか?
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 を合計すると、それは単なる合計に
なります 通常の合計は、次のように fold を使用して表すことができます
sum = fold (+) 0
ここで、0 は合計のシードとして表示できます。ghci に次の 2 つの式を入力することを納得させるために
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 を pred 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) []