reduceを使う
次にreduceを使います。reduceとは,
今やりたいことは,
((((0 + 0) + 20) + 60) + 120) + 200
つまり,
> foldl (+) 0 ret2
400
答えが出てきました!
プログラムにまとめる
では,
> let mul (i,x) = x * i
> let calc xs = foldl (+) 0 (map mul (zip [0..] xs))
Haskellでは,
> calc [10,20,30,40,50]
400
再代入なしに問題が解けました!
このように関数型言語では,
ファイルに書き出す
これまで対話環境でプログラムを作成してきましたが,
mul (i,x) = x * i
calc xs = foldl (+) 0 (map mul (zip [0..] xs))
対話環境ではないので,
% ghci calc.hs
Main>
ファイルを読み込むとプロンプトがPrelude>
から変化します。以降はこちらも>と略記します。
calcを使ってみましょう。
> calc [10,20,30,40,50]
400
calc.
繰り返しと再帰との関係
再代入なしでも,
リストを走査するという繰り返しの機能は,
map f [] = []
-- mapがmap自身を呼び出している
map f (x:xs) = f x : map f xs
このプログラムの意味を理解する必要はありません。mapがmap自身を呼び出しているのがわかれば十分です。このように関数プログラミングでは,
関数プログラミングの特徴:部品プログラミング
関数型言語では,
例として,
> let mapMul = map mul
mapは二引数の関数でしたが,
> mapMul [(0,10),(1,20),(2,30)]
[0,20,60]
また,
let calc = foldl (+) 0 . map mul . zip [0..]
このプログラムの意味が正確にわからなくてもかまいません。ただ,
関数プログラミングでは,
- 汎用の部品である高階関数を部分適用でカスタマイズして新たな部品を作る
- それらをつなぎ合わせてさらに大きな部品を作る
ここで,